爬虫便捷操作之selenium使用技巧
selenium
在爬虫中占据比较重要的地位
- 是一种浏览器自动化的工具,所谓的自动化是指,我们可以通过代码的形式制定一系列的行为动作,然后执行代码,这些动作就会同步触发在浏览器中。
我们在抓取一些普通网页的时候requests基本上是可以满足的. 但是, 如果遇到一些特殊的网站. 它的数据是经过加密的.
但是呢, 浏览器却能够正常显示出来. 那我们通过requests抓取到的内容可能就不是我们想要的结果了. 例如,
电影票房数据. 在浏览器上看的时候是正常的. 那么按照之前的逻辑. 我们只需要看看数据是通过哪个请求拿到的就可以进行模拟请求了. 但是!
数据找到了. 接着看"预览"吧
我们发现这个数据是经过加密算法的. 这就头疼了. 直接通过requests拿到这些内容必须要解密才能看到真实数据.
但是该网站采用的加密方式又不是那么容易破解. 此时, 各位想想如果我能通过我的程序直接调用浏览器.
让浏览器去解密这些内容. 我们直接拿结果岂不妙哉. 哎~这就引出了我们本章要讲解的selenium了. 它可以完美解决上述问题
简单介绍一下selenium, 它本身是一个自动化测试的工具. 可以启动一个全新的浏览器.并从浏览器中提取到你想要的内容. 随着各种网站的反爬机制的出现.
selenium越来越受到各位爬sir的喜爱. selenium最大的缺点其实就一个, 慢! 你想啊. 他要启动一个第三方的软件(浏览器), 并且还要等待浏览器把数据渲染完毕. 这个过程必然是很耗时的. 所以它慢.
接下来, 我们来聊聊selenium如何安装和使用.
环境安装
- 下载安装selenium:pip install selenium
- 下载浏览器驱动程序: 谷歌浏览器驱动
- http://chromedriver.storage.googleapis.com/index.html
- 查看驱动和浏览器版本的映射关系:
- http://blog.csdn.net/huilan_same/article/details/51896672
edge驱动:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
先看自己浏览器版本
然后下载对应版本驱动
下载后解压
edge浏览器,需要将驱动包放在python解释器位置,并改名为MicrosoftWebDriver.exe
selenium4.11.2版本很不好用,我们使用低一点的版本
使用selenium3.141.0时,会出现一些报错
显示ValueError: Timeout value connect was ……, but it must be an int, float or None
urllib3版本 需要把urllib3版本降级到1.26.2后,错误全部消失
如此,就可以正常使用了
效果展示
from selenium import webdriver
from time import sleep
#后面是你的浏览器驱动位置,记得前面加r’‘,‘r’是防止字符转义的
driver = webdriver.Chrome(r’./chromedriver’)
#用get打开百度页面
driver.get(“http://www.baidu.com”)
#查找页面的“设置”选项,并进行点击
driver.find_element_by_xpath(‘//*[@id=“s-usersetting-top”]’).click()
sleep(2)
#打开设置后找到“搜索设置”选项,设置为每页显示50条
driver.find_elements_by_link_text(‘搜索设置’)[0].click()
sleep(2)
#选中每页显示50条
m = driver.find_element_by_xpath(‘//*[@id=“nr_3”]’).click()
sleep(2)
#点击保存设置
driver.find_element_by_xpath(‘//*[@id=“se-setting-7”]/a[2]’).click()
sleep(2)
#处理弹出的警告页面 确定accept() 和 取消dismiss()
driver.switch_to_alert().accept()
sleep(2)
#找到百度的输入框,并输入 美女
driver.find_element_by_id(‘kw’).send_keys(‘美女’)
sleep(2)
#点击搜索按钮
driver.find_element_by_id(‘su’).click()
sleep(2)
#在打开的页面中找到“Selenium - 开源中国社区”,并打开这个页面
driver.find_element_by_xpath(‘//*[@id=“1”]/div/h3/a’).click()
sleep(3)
#关闭浏览器
driver.quit()
浏览器创建
Selenium支持非常多的浏览器,如Chrome、Firefox、Edge等.另外,也支持无界面浏览器。
from selenium import webdriver
browser = webdriver.Chrome()
browser = webdriver.Firefox()
browser = webdriver.Edge()
browser = webdriver.PhantomJS()
browser = webdriver.Safari()
元素定位
webdriver 提供了一系列的元素定位方法,常用的有以下几种:
find_element_by_id()
find_element_by_name()
find_element_by_class_name()
find_element_by_tag_name()
find_element_by_link_text()
find_element_by_xpath()
find_element_by_css_selector()
节点交互
Selenium可以驱动浏览器来执行一些操作,也就是说可以让浏览器模拟执行一些动作。
比较常见的用法有:输入文字时用send_keys()
方法,清空文字时用clear()
方法,点击按钮时用click()
方法。
执行js
对于某些操作,Selenium API并没有提供。比如,下拉进度条,它可以直接模拟运行JavaScript,此时使用execute_script()方法即可实现。
from selenium import webdriver
from time import sleep
#后面是你的浏览器驱动位置,记得前面加r’','r’是防止字符转义的
#由于谷歌浏览器最新的驱动没找到,我们使用edge浏览器
driver = webdriver.Edge()
#用get打开百度页面
#driver.get(“https://www.baidu.com”)
#打开京东
driver.get(“https://jd.com”)
sleep(2)
#标签定位,输入商品
search_box = driver.find_element_by_xpath(‘//*[@id=“key”]’)
sleep(2)
#节点交互
search_box.send_keys(‘mac pro’) #向指定标签中录入内容
sleep(2)
#点击搜索
driver.find_element_by_xpath(‘//*[@id=“search”]/div/div[2]/button’).click()
sleep(3)
#js注入,将要执行的js代码放进去
driver.execute_script(‘document.documentElement.scrollTo(0,2000)’)
sleep(5)
#sleep(3)
driver.close()
思考:在爬虫中为什么需要使用selenium?selenium和爬虫之间的关联是什么?
- 便捷的爬取动态加载数据(可见即可得) 不用管数据是否动态加载,只要selenuim打开web页面,能看到数据,都能爬到数据
#获取前5页的企业名称
from selenium import webdriver
import time
from lxml import etree
bro = webdriver.Chrome(executable_path=‘./chromedriver’)
url = ‘http://scxk.nmpa.gov.cn:81/xk/’
bro.get(url=url)
time.sleep(1)
#获取页面源码数据(page_source)
page_text = bro.page_source
#将前5页的页面源码数据存储到该列表中
all_page_text_list = [page_text]
for i in range(4):
#点击下一页
next_page_btn = bro.find_element_by_xpath(‘//*[@id=“pageIto_next”]’)
next_page_btn.click()
time.sleep(1)
all_page_text_list.append(bro.page_source)
for page_text in all_page_text_list:
#解析数据
tree = etree.HTML(page_text)
li_list = tree.xpath(‘//*[@id=“gzlist”]/li’)
for li in li_list:
title = li.xpath(‘./dl/@title’)[0]
print(title)
time.sleep(2)
bro.quit()
使用selenium获取公司验证码地址,这个之前通过requests获取不到
from selenium import webdriver
from time import sleep
from lxml import etree
#由于谷歌浏览器最新的驱动没找到,我们使用edge浏览器
driver = webdriver.Edge()
driver.get(‘https://tfi.guokinghk.com/operationadmin/login’)
sleep(2)
page_text = driver.page_source
tree = etree.HTML(page_text)
image_src = tree.xpath(‘/html/body/div[1]/div[1]/div[2]/form/div[1]/div[3]/div/div[4]/div/div/span/span/span/img/@src’)[0]
print(image_src)
sleep(2)
driver.close()
让网页数据无处遁形
便捷实现模拟登录
- 后面在说
获取页面源码数据
通过page_source
属性可以获取网页的源代码,接着就可以使用解析库(如正则表达式、Beautiful Soup、pyquery等)来提取信息了。
前进和后退
#模拟浏览器的前进后退
from selenium import webdriver
import time
browser = webdriver.Chrome(r’./chromedriver’)
browser.get(‘https://www.baidu.com’)
browser.get(‘https://www.taobao.com’)
browser.back()
time.sleep(2)
browser.forward()
time.sleep(2)
browser.close()
selenium获取动态加载数据
- 实现可见即可得
动作链
在上面的实例中,一些交互动作都是针对某个节点执行的。
比如,对于输入框,我们就调用它的输入文字和清空文字方法;
对于按钮,就调用它的点击方法。
其实,还有另外一些操作,它们没有特定的执行对象,比如鼠标拖曳、键盘按键等,这些动作用另一种方式来执行,那就是动作链。
先看页面
from selenium.webdriver import ActionChains
from selenium import webdriver
from time import sleep
bro = webdriver.Chrome(executable_path=‘./chromedriver’)
bro.get(‘https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable’)
sleep(1)
#注意:如果定位的标签是存在于iframe表示的子页面中,则常规的标签定位报错。
#处理:使用如下指定操作,先切换到iFrame,根据id来切换
bro.switch_to.frame(‘iframeResult’)
div_tag = bro.find_element_by_id(‘draggable’)
#实例化一个动作链对象且将该对象绑定到指定的浏览器中
action = ActionChains(bro)
action.click_and_hold(div_tag) #对指定标签实现点击且长按操作
for i in range(5):
action.move_by_offset(10,10).perform() #perform让动作链立即执行
sleep(0.5)
sleep(3)
bro.quit()
切换iframe案例:
from selenium import webdriver
import time
from lxml import etree
from selenium.webdriver.chrome.options import Options
import os
import json
import requests
import re
def login():
#规避检测环节1
chrome_options = Options()
# chrome_options.add_argument(‘–headless’)
# chrome_options.add_argument(“–no-sandbox”)
chrome_options.add_argument(‘–disable-gpu’)
# chrome_options.add_argument(“–disable-extensions”)
chrome_options.add_argument(“–disable-blink-features=AutomationControlled”)
chrome_options.add_argument(‘user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36’)
chrome_options.add_argument(‘–start-maximized’) # 浏览器窗口最大
# chrome_options.add_argument(‘–lang=en_US’)
# 驱动路径
path = r'D:\downloads\chromedriver-win64\chromedriver.exe'
bro = webdriver.Chrome(executable_path=path,options=chrome_options)
bro.get('https://qian.cainiao.com/login#/login?_k=jocblt')
time.sleep(2)
#找到iframe,并切换。通过xpath查找
#//*[@id="loginBox"]
iframe = bro.find_element_by_xpath('//*[@id="loginBox"]')
time.sleep(1)
bro.switch_to.frame(iframe)
time.sleep(1)
#再次切换
#//*[@id="alibaba-login-box"]
iframe2 = bro.find_element_by_xpath('//*[@id="alibaba-login-box"]')
time.sleep(1)
bro.switch_to.frame(iframe2)
#//*[@id="login-tabs"]/div[2]
#//*[@id="login-tabs"]/div[2]
time.sleep(1)
bro.find_element_by_xpath('//*[@id="login-tabs"]/div[2]').click()
time.sleep(2)
#//*[@id="fm-sms-login-id"]
bro.find_element_by_xpath('//*[@id="fm-sms-login-id"]').send_keys('18822806868')
time.sleep(2)
#//*[@id="login-form"]/div[2]/div[3]/a
bro.find_element_by_xpath('//*[@id="login-form"]/div[2]/div[3]/a').click()
print("已发送")
time.sleep(3)
bro.close()
if name == ‘main’:
login()
带验证码的模拟登录
-
登录bilibili
- https://passport.bilibili.com/login?from_spm_id=333.851.top_bar.login_window
我们使用最新的url登录:https://www.bilibili.com/
- 识别验证码模块封装:
做模拟登录的目的是通过爬虫程序,拿到登录成功之后页面的数据 比如抓取我的关注列表,我的粉丝等
from selenium import webdriver
from time import sleep
from tujian import tijian
#导入动作链模块
from selenium.webdriver import ActionChains
#由于谷歌浏览器最新的驱动没找到,我们使用edge浏览器
driver = webdriver.Edge()
driver.get(‘https://www.bilibili.com/’)
sleep(2)
#找到登录按钮,点击登录
driver.find_element_by_xpath(‘//*[@id=“i_cecream”]/div[2]/div[1]/div[1]/ul[2]/li[1]/li/div[1]/div/span’).click()
sleep(2)
#如果定位的标签在iFrame中,定位之前要先做切换iFrame操作,切换根据iFrame的id来操作,否则报错
#定位到输入用户名密码标签,输入用户名和密码
#/html/body/div[3]/div/div[4]/div[2]/form/div[1]/input
#/html/body/div[5]/div/div[4]/div[2]/form/div[1]/input
username = driver.find_element_by_xpath(‘/html/body/div[3]/div/div[4]/div[2]/form/div[1]/input’)
sleep(2)
username.send_keys(‘13xxx559785’)
pwd = driver.find_element_by_xpath(‘/html/body/div[3]/div/div[4]/div[2]/form/div[3]/input’)
sleep(1)
pwd.send_keys(‘jingfsgsg3’)
sleep(1)
#点击登录
driver.find_element_by_xpath(‘/html/body/div[3]/div/div[4]/div[2]/div[2]/div[2]’).click()
sleep(5)
#4.定位完整的验证码对话框
#注意:在开发者工具中是可以定位到多个div表示验证码对话框的,因此将这几个div都定位到,依次去尝试
#这里一定要将弹出的验证码框定位全
code_tag = driver.find_element_by_xpath(‘/html/body/div[4]/div[2]/div[6]/div/div’)
sleep(1)
#5.识别验证码(使用打码平台进行验证码识别).screenshot可以将验证码对话框截图保存
code_tag.screenshot(‘tujian/code.png’) #将验证码对话框截图保存,建议保存.png后缀的图片
sleep(1)
#使用图鉴接口识别,识别出来的是个列表
result = tijian.getCodeText(‘tujian/code.png’,27)#获取了识别的结果
#27类型,可以识别1-4个坐标,就是1-4个字的坐标
#result = ‘154,251|145,167’
print(result)
#根据|切分,得到每个字的坐标列表
result_list = result.split(‘|’)
print(result_list)
#6.根据识别出验证码的结果进行处理,有几个字,就要滑动点击几次
for pos in result_list:
x = int(pos.split(‘,’)[0]) #得到的是字符串类型,需要强转
y = int(pos.split(‘,’)[1])
#使用动作链去点击,移动到验证码图片坐标
ActionChains(driver).move_to_element_with_offset(code_tag,x,y).click().perform()
sleep(0.5)
#识别验证码后,点击确认登录
confirm_btn = driver.find_element_by_xpath(‘/html/body/div[4]/div[2]/div[6]/div/div/div[3]/a/div’)
confirm_btn.click()
sleep(30)
driver.close()
Cookie 后续如果使用requests登录,就需要使用cookie来免登陆
使用Selenium,还可以方便地对Cookies进行操作,例如常见的获取Cookies,示例如下:
- get_cookies()返回值是由字典组成的列表,叫做jsonCookies。
- 需要将jsonCookies解析成浏览器携带的cookie形式
#获取jsonCookies
from selenium import webdriver
import time
browser = webdriver.Chrome(r’./chromedriver’)
browser.get(‘https://www.zhihu.com/explore’)
print(browser.get_cookies())
browser.close()
获取的cookie是列表套字典形式
解析jsonCookies成浏览器的cookie形式
是不是字典中的字段都是cookie呢,不是的,我们打开浏览器开发者模式,随便看个网站的cookie
是由name和value组成,所以我们解析时,只需要解析出name和value对应的值即可
解析出网站的cookie
from selenium import webdriver
from time import sleep
#由于谷歌浏览器最新的驱动没找到,我们使用edge浏览器
driver = webdriver.Edge()
#获取知乎的cookie
driver.get(‘https://www.zhihu.com/explore’)
sleep(2)
#获取cookie
cookies = driver.get_cookies()
print(cookies)
#解析cookie
dic = {}
for cookie in cookies:
key = cookie[‘name’]
value = cookie[‘value’]
dic[key] = value
print(dic) #在爬虫中可以使用的cookie
driver.close()
每个字典中都有name value字段,提取出来
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!