爬虫便捷操作之selenium使用技巧

2024-01-02 09:28:55

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字段,提取出来
在这里插入图片描述

文章来源:https://blog.csdn.net/littlefun591/article/details/135292305
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。