系列文章目录
第一章 爬虫——爬虫初识、requests模块
第二章 代理搭建、爬取视频网站、爬取新闻、BeautifulSoup4介绍、bs4 遍历文档树、bs4搜索文档树、bs4使用选择器
第三章 selenium基本使用、无界面浏览器、selenium的其他用法、selenium的cookie、爬虫案例
第四章 动作链、xpath、打码平台使用
一、selenium基本使用
由于requests不能执行js,有的页面内容,我们在浏览器中可以看到,但是响应中并没有对应数据,这个时候可以使用selenium模块。 selenium:模拟人操作浏览器,完成人的行为
selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题
selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器
1.安装selenium
pip install selenium
2.下载浏览器驱动
由于selenium需要操作浏览器,所以我们还需要准备浏览器驱动 此处以谷歌为例: 谷歌浏览器驱动由于墙的原因无法访问,所以可以使用淘宝提供的镜像站 谷歌浏览器驱动镜像站
查看谷歌浏览器版本 第一种:在设置中找到关于浏览器即可 第二种: 在地址栏输入
chrome://version/
3.selenium的基础使用
驱动程序放在项目路径下或者环境变量中
from selenium import webdriver
bro=webdriver.Edge()
bro.implicitly_wait(10)
bro.get('https://www.baidu.com')
bro.close()
bro.quite()
模拟登陆百度
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
bro = webdriver.Chrome()
bro.implicitly_wait(10)
bro.get('https://www.baidu.com/')
btn = bro.find_element(by=By.LINK_TEXT, value='登录')
btn.click()
username = bro.find_element(by=By.ID, value='TANGRAM__PSP_11__userName')
password = bro.find_element(by=By.ID, value='TANGRAM__PSP_11__password')
username.send_keys('百度账号')
password.send_keys('百度密码')
btn_login=bro.find_element(by=By.ID,value='TANGRAM__PSP_11__submit')
btn_login.click()
bro.close()
4.selenium的基础方法
4.1 查找控件
find_element_by_id
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_name
find_element_by_css_selector
find_element_by_xpath
bro.find_element(by=By.ID,value='TANGRAM__PSP_11__submit')
4.2 点击某个按钮
标签对象.click()
submit_btn = bro.find_element(by=By.ID,value='TANGRAM__PSP_11__submit')
submit_btn.click()
4.3 向输入框中写内容
标签对象.send_keys(内容)
username_input = bro.find_element(by=By.ID,value='username')
username_input.send_keys('kkkk23123')
二、selenium无界面浏览器
使用selenium操作浏览器时,并不是时时刻刻都需要观看图形化界面的,这个时候可以设置我界面浏览器,并且可以获取当前html内容
from selenium.webdriver.edge.options import Options
edge_options = Options()
edge_options.add_argument('window-size=1920x3000')
edge_options.add_argument('--hide-scrollbars')
edge_options.add_argument('blink-settings=imagesEnabled=false')
edge_options.add_argument('--headless')
driver=webdriver.Edge(options=edge_options)
driver.get('https://www.cnblogs.com/')
print(driver.page_source)
driver.close()
三、selenium的其他用法
1. 获取位置属性大小,文本
标签.location 该标签在浏览器中的位置,以该标签左上角为基准 标签.size 该标签的大小 标签.id 不是标签的id号,而是该标签在整个html中的唯一标识 标签.tag_name 该标签的名字 标签.get_attribute(‘src’) 获取该标签的属性例如:width、src、height、css、id等
接下来以12306为例,获取扫码登录时的二维码的信息,并且将该二维码作为图片保存下来
import time
import base64
from selenium import webdriver
from selenium.webdriver.common.by import By
bro=webdriver.Edge()
bro.get('https://kyfw.12306.cn/otn/resources/login.html')
bro.implicitly_wait(10)
btn=bro.find_element(By.LINK_TEXT,'扫码登录')
btn.click()
time.sleep(1)
img=bro.find_element(By.ID,'J-qrImg')
print(img.location)
print(img.size)
print(img.id)
print(img.tag_name)
s=img.get_attribute('src')
with open('code.png','wb') as f:
res=base64.b64decode(s.split(',')[-1])
f.write(res)
bro.close()
2. 等待元素被加载
程序操作页面非常快,所以在取每个标签的时候,标签可能没有加载号,需要设置等待 等待有俩种:
- 强制等待:使用time.sleep(),无论什么情况一定会等待
- 显式等待:当等待的条件满足后(一般用来判断需要等待的元素是否加载出来),就继续下一步操作。等不到就一直等,如果在规定的时间之内都没找到,那么就跳出Exception。
- 隐式等待:selenium对象.implicitly_wait(10)
2.1强制等待
直接在代码中调用time.sleep即可
2.2显式等待
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wd = webdriver.Edge()
wd.get('https://www.baidu.com')
login_btn=WebDriverWait(wd,10,0.5).until(EC.presence_of_element_located((By.ID, "s-top-loginbtn")))
login_btn.click()
2.3隐式等待
隐式等待是全局设置,一次设置后全局生效 隐式等待设置了一个最长等待时间,在规定时间内网页加载完成(也就是一般情况下你看到浏览器标签栏那个小圈不再转就代表加载完成),则执行下一步,否则一直等到时间结束,然后执行下一步。
from selenium import webdriver
from selenium.webdriver.common.by import By
bro=webdriver.Edge()
bro.implicitly_wait(10)
bro.get('https://www.baidu.com')
3. 元素操作
3.1搜索标签
方法 | 作用 |
---|
find_element | 找第一个,搭配By可以实现下面的其他方法 | find_elements | 找所有,搭配By可以实现下面的其他方法 | find_element_by_id | 根据id | find_element_by_link_text | 根据a标签的文字 | find_element_by_partial_link_text | 根据a标签的文字模糊匹配 | find_element_by_tag_name | 根据标签名 | find_element_by_class_name | 根据类名 | find_element_by_name | 根据name属性 | find_element_by_css_selector | css选择器 | find_element_by_xpath | xpath |
find_element与find_elements如下: selenium对象.find_element(by=By.ID,value=‘TANGRAM__PSP_11__submit’) selenium对象.find_elements(By.LINK_TEXT, ‘美好的一天’)
3.2 点击
标签.click()
3.3 写入文字
标签.send_keys(value)
3.4 清空
标签.clear()
3.5 滑动屏幕到底部
selenium对象.execute_script('scrollTo(0,document.body.scrollHeight)')
4. 执行js代码
selenium对象.execute_script(js代码)
5. 切换选项卡
selenium对象.execute_script('window.open()')
selenium对象.switch_to.window(selenium对象.window_handles[1])
6. 浏览器前进后退
selenium对象.back()
selenium对象.forward()
7. 异常处理
在进行浏览器操作时使用try except来进行
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException,NoSuchElementException,NoSuchFrameException
bro=webdriver.Edge()
try:
bro.get('https://www.pearvideo.com/category_8')
time.sleep(1)
bro.get('https://www.baidu.com')
raise Exception('报错了')
except Exception as e:
print(e)
finally:
bro.quit()
四、selenium的cookie
selenium对象.get_cookies()
selenium对象.add_cookie()
五、爬虫案例
使用selenium对博客园任意页全部进行点赞
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
import requests
bro = webdriver.Edge()
bro.implicitly_wait(10)
def login():
bro.get('https://account.cnblogs.com/')
username = bro.find_element(By.ID, 'mat-input-0')
password = bro.find_element(By.ID, 'mat-input-1')
username.send_keys('')
password.send_keys('')
input()
cookie = bro.get_cookies()
with open('./cookie.json', 'w', encoding='utf-8') as f:
json.dump(cookie, f)
def is_login():
bro.get('https://account.cnblogs.com/')
with open('cookie.json', 'r', encoding='utf-8') as f:
res = json.load(f)
for item in res:
bro.add_cookie(item)
bro.get('https://account.cnblogs.com/')
bro.refresh()
def aricte_dig_up(start, stop):
home = bro.find_element(By.CSS_SELECTOR,
'body > app-root > app-main-layout > app-navbar > mat-toolbar > mat-toolbar-row > div:nth-child(1) > a.mat-tooltip-trigger.logo')
home.click()
for i in range(start, stop+1):
pag = bro.find_element(By.CSS_SELECTOR, '#paging_block > div > a.p_%s.current'%i)
pag.click()
arictes = bro.find_elements(By.CSS_SELECTOR, '#post_list article')
aricte_ids = []
for aricte in arictes:
aricte_ids.append(aricte.get_attribute('data-post-id'))
for post_id in aricte_ids:
up_btn = bro.find_element(By.ID, 'digg_control_%s'%post_id)
up_btn.click()
if __name__ == '__main__':
key = False
if key:
login()
else:
is_login()
aricte_dig_up(1, 1)
bro.close()
|