Python爬虫编程6——selenium

367次阅读
没有评论

目录

爬虫和反爬虫的斗争

爬虫建议

ajax基本介绍

动态了解HTML技术

获取ajax数据的方式

一.Selenium+chromedriver

Selenium介绍

Phantomjs快速入门

Phantomjs案例

selenium快速入门

定位元素

操作表单数据

鼠标行为链

Selenium页面等待

Cookie操作

页面等待

打开多窗口和切换页面

特征识别和设置无头窗口

selenium常用的js操作

二.图形验证码识别

Tesseract安装以及操作

云打码平台的使用


爬虫和反爬虫的斗争

Python爬虫编程6——selenium

爬虫建议

(1)尽量减少请求次数,保存或取的HTML,供查错和重复使用;

(2)关注网站的所有类型的页面,H5页面,APP等等;

(3)设置多伪装,代理IP,随即请求头等;

(4)利用多线程分布式,再不被发现的情况下我们尽可能提高速度。

ajax基本介绍

动态了解HTML技术

(1)JS:是网络上最常用的脚本语言,它可以收集用户的跟踪数据,不需要重载页面直接提交表单,在页面嵌入多媒体文件,甚至运行网页;

(2)jQuery:jQuery是一个快速,简介的JavaScript框架,封装了JavaScript常用的功能代码;

(3)ajax:ajax可以使用网页实现异步更新,可以在不重新加载整个页面的情况下,对页面的某部分进行更新。

获取ajax数据的方式

(1)直接分析ajax调用的接口。然后通过代码请求这个接口;

(2)使用Selenium+chromedriver模拟浏览器行为获取数据;

Python爬虫编程6——selenium

一.Selenium+chromedriver

Selenium介绍

1.selenium是一个web的自动化测试工具,最初是为网站自动化测试而开发的,selenium可以直接运行在浏览器上,它支持所有主流的浏览器,可以接受指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏。

2.chromedriver是一个驱动Chorme浏览器的驱动程序,使用它才可以驱动浏览器。当然针对不同的浏览器有不同的driver。以下列出了不同浏览器及其对应的driver:

(1)Chrome:https://sites.google.com/a/chromium.org/chromedriver/downloads

(2)Firefox:Releases · mozilla/geckodriver · GitHub

(3)Edge:Microsoft Edge Driver – Microsoft Edge Developer

(4)Safari:WebDriver Support in Safari 10 | WebKit

  • 下载chromedriver
  • 百度搜索:淘宝镜像(npmmirror 中国镜像站)
  • 安装总结:Selenium 入门教程(Python) – 简书
  • 安装Selenium:pip install selenium
  • 新的chromedriver 第地址 http://chromedriver.storage.googleapis.com/index.html

Phantomjs快速入门

无头浏览器:一个完整的浏览器内核,包含js解析引擎,渲染引擎,请求处理等,但是不包含显示和用户的页面的浏览器。

Phantomjs案例

# 1.加载网页 from selenium import webdriver driver = webdriver.PhantomJS("安装目录") driver.get("https://www.baidu.com") driver.save_screenshot("baidu.png")

# 2.定位和操作 driver.find_element_by_id("kw").send_keys("长城") driver.find_element_by_id("su").click()

# 3.查看请求信息 driver.page_source driver.get_cookies() driver.current_url

# 4.退出 driver.quit()

注意:在新版的selenium中没有Phantomjs,所以这里不做更多的解释。

selenium快速入门

from selenium import webdriver

# 实例化浏览器 driver = webdriver.Chrome()

# 发送请求 driver.get('https://www.baidu.com')

# 退出浏览器 driver.quit()

定位元素

(1)find_element_by_id:根据id查找某个元素:

submitTag = driver.find_element_by_id('su') submitTag1 = driver.find_element(By.ID,'su')

(2)find_element_by_class_name:根据类名查找某个元素:

submitTag = driver.find_element_by_class_name('su') submitTag1 = driver.find_element(By.CLASS_NAME,'su')

(3)find_element_by_name:根据name属性值查找某个元素:

submitTag = driver.find_element_by_name('email') submitTag1 = driver.find_element(By.NAME,'email')

(4)find_element_by_tag_name:根据标签名查找某个元素:

submitTag = driver.find_element_by_tag_name('div') submitTag1 = driver.find_element(By.TAG_NAME,'div')

(5)find_element_by_xpath:根据xpath语法查找某个元素:

submitTag = driver.find_element_by_xpath('//div') submitTag1 = driver.find_element(By.XPATH,'//div')

注意使用上述的小by方法定位元素时,会有一个报警,这是因为这个方法即将过时,而大By方法,则不会出现报警,但是要导包:

from selenium.webdriver.common.by import By

且注意,find_element是获取第一个满足条件的元素。find_elements是获取所有满足条件的元素。

操作表单数据

操作输入框:分为两步。

第一步:找到这个元素。

第二步:使用send_keys(values),将数据填充进去。

(1)使用clear方法可以清除输入框中的内容

inputTag.clear()

(2)操作按钮

操作按钮有很多种方式,比如单击,右击,双击等。这里讲两个最常用的。就是点击,直接调用click函数就可以了。

inputTag = driver.find_element_by_id('su') # 点击函数 inputTag.click()

(3)选择select

select元素不能直接点击。因为点击后还需要选中元素。这时候selenium就专门为select标签提供了一个类from selenium.webdriver.support.ui import Select。将获取到的元素当成参数传到这个类中,创建这个对象。以后就可以使用这个对象进行选择了。(注意有时要切换到一个新的标签iframe中)

测试网站:https://www.17sucai.com/pins/demo-show?id=5926

from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import Select import time

driver = webdriver.Chrome() driver.get('https://www.17sucai.com/pins/demo-show?id=5926')

# 找到iframe iframe_tag = driver.find_element_by_id('iframe') # 切换到iframe # 旧方法 # driver.switch_to_frame(iframe_tag) # 新方法 driver.switch_to.frame(iframe_tag)

# 定位到select标签 # Message: no such element: Unable to locate element: {"method":"css selector","selector":".nojs"} select_tag = driver.find_element_by_class_name('nojs')

new_select_tag = Select(select_tag)

# 根据值来选择 # new_select_tag.select_by_value('AU')

# 根据索引选择 new_select_tag.select_by_index(1) """ 两种选择方式 一种是根据值来选择 另一种是通过索引选择 """

鼠标行为链

有时候在页面中的操作可能要有很多步,那么这时候可以使用鼠标行为链类ActionChains来完成。比如现在要将鼠标移动到某个元素上并执行点击事件。

import time from selenium.webdriver.common.by import By

driver = webdriver.Chrome() driver.get('https://www.baidu.com/?tn=49055317_3_hao_pg')

# 定位输入框 input_baidu = driver.find_element(By.XPATH, '//*[@id="kw"]')

# 定位百度按钮 btn_baidu = driver.find_element(By.XPATH, '//*[@id="su"]')

actions = ActionChains(driver)

# 往输入框种输入内容 actions.send_keys_to_element(input_baidu, 'python') time.sleep(2) # 移动鼠标位置 actions.move_to_element(btn_baidu) actions.click()

# 提交行为链,必不可少 actions.perform()

还有更多的鼠标相关的操作

  • click_and_hold(element):点击但不松开鼠标。
  • context_click(element):右键点击。
  • double_click(element):双击。
  • 更多方法请参考:7. WebDriver API — Selenium Python Bindings 2 documentation

行为链小练习:

from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By import time

# 1 找到滑块 # 2 拖动小滑块 # 3 到大滑块松开鼠标

driver = webdriver.Chrome()

driver.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')

ifarme = driver.find_element(By.ID,'iframeResult')

driver.switch_to.frame(ifarme)

# 小滑块 div1 = driver.find_element(By.ID,'draggable')

# 大滑块 div2 = driver.find_element(By.ID,'droppable')

# 创建行为链 ac = ActionChains(driver)

# 点击并且不松开 ac.click_and_hold(div1)

# 拖动到大的div # ac.move_to_element(div2)

# ac.move_by_offset(300,0) for i in range(6): time.sleep(0.1) ac.move_by_offset(50, 0)

# 松开鼠标 ac.release()

# 提交行为链 ac.perform()

测试网站:https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable

Selenium页面等待

Cookie操作

(1)获取所有的cookie

cookies = driver.get_cookies()

(2)根据cookie的name获取cookie

value = driver.get_cookie(name)

(3)删除某个cookie

driver.delete_cookie('key')

案例:利用selenium得到的cookie登录qq空间:

from selenium import webdriver from selenium.webdriver.common.by import By import time import requests

# 通过selenium获取cookie """ 1 通过selenium获取cookie值 2 进一步解析拼接cookie值 3 把最终拼接好的cookie值放测试代码中做测试 """ # 1 通过selenium获取cookie值 # 加载驱动 driver = webdriver.Chrome() # 打开一个网站 driver.get('https://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=https%3A//qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=https%3A%2F%2Fqzs.qzone.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone&pt_qr_app=手机QQ空间&pt_qr_link=http%3A//z.qzone.com/download.html&self_regurl=https%3A//qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=http%3A//z.qzone.com/download.html&pt_no_auth=0')

time.sleep(2)

# 找到头像 # link = driver.find_element_by_id('img_out_2857223830') link = driver.find_element_by_class_name('face') # 点击 link.click() # 等待页面加载一会儿 time.sleep(2) raw_cookie = driver.get_cookies() # print(raw_cookie) # 列表推导式 cookie = [item['name'] + '=' + item['value'] for item in raw_cookie] # cookie_plus = "; ".join(cookie) cookie_plus = "; ".join(i for i in cookie) print(cookie_plus)

# cookie = [] # for i in raw_cookie: # n = i['name'] # v = i['value'] # # n=v # lst = n + '=' + v # cookie.append(lst) # # print(cookie) # cookie_plus = "; ".join(cookie) # print(cookie_plus)

# 测试代码 如果把通过selenium获取到的cookie放进请求头中 能够模拟登录成功 就证明我们通过selenium获取到的cookie是没有问题的 # url = 'https://user.qzone.qq.com/2857223830/infocenter' # # header = { # 'cookie': cookie_plus, # 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36' # } # # html = requests.get(url, headers=header) # with open('qzone.html', 'w', encoding='utf-8') as f: # f.write(html.content.decode('utf-8'))

页面等待

现在的网页越来越多采用了 Ajax 技术,这样程序便不能确定何时某个元素完全加载出来了。如果实际页面等待时间过长导致某个dom元素还没出来,但是你的代码直接使用了这个WebElement,那么就会抛出NullPointer的异常。为了解决这个问题。所以 Selenium 提供了两种等待方式:一种是隐式等待、一种是显式等待。

(1)隐式等待:调用driver.implicitly_wait。那么在获取不可用的元素之前,会先等待10秒中的时间。

driver.implicitly_wait(10)

(2)显式等待:显示等待是表明某个条件成立后才执行获取元素的操作。也可以在等待的时候指定一个最大的时间,如果超过这个时间那么就抛出一个异常。显示等待应该使用selenium.webdriver.support.excepted_conditions期望的条件和selenium.webdriver.support.ui.WebDriverWait来配合完成。

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

driver = webdriver.Chrome() driver.get("https://www.baidu.com/")

element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "myDynamicElement")) )

一些其他的等待条件

  • presence_of_element_located:某个元素已经加载完毕了。
  • presence_of_all_elements_located:网页中所有满足条件的元素都加载完毕了。
  • element_to_be_clickable:某个元素是可以点击了。
  • 更多条件请参考:5. Waits — Selenium Python Bindings 2 documentationPython爬虫编程6——seleniumhttp://selenium-python.readthedocs.io/waits.html

打开多窗口和切换页面

有时候窗口中有很多子tab页面。这时候肯定是需要进行切换的。selenium提供了一个叫做switch_to_window来进行切换,具体切换到哪个页面,可以从driver.window_handles中找到。

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 import time

driver = webdriver.Chrome() driver.get('https://www.baidu.com/?tn=49055317_3_hao_pg') driver.implicitly_wait(3) # driver.get('https://www.douban.com/?tn=49055317_3_hao_pg') # 用js打开多个窗口 driver.execute_script('window.open("https://www.douban.com/?tn=49055317_3_hao_pg")') time.sleep(2) # 打开一个新窗口,如果想对新窗口进行操作,就要先切换selenium的视角 driver.switch_to.window(driver.window_handles[1]) # 打印当前视角的url print(driver.current_url) driver.close() # 使用close关闭之后,最好切换一下窗口,有残留。最好不要使用

特征识别和设置无头窗口

(1)设置无头窗口(运行时不会在打开浏览器)

from selenium import webdriver

# 创建一个设置对象 option = webdriver.ChromeOptions() option.add_argument('–headless')

driver = webdriver.Chrome(options=option)

driver.get('https://www.baidu.com')

driver.save_screenshot('baidu.png')

(2)特征识别

有时候我们在使用selenium爬取某网站时,会被网站识别成一个自动化测试的程序,从而会导致我们得不到想要的数据,我们这时需要去除一下特征识别:

from selenium import webdriver import time from selenium.webdriver.common.by import By

# 去除识别 去除提示框 # option = webdriver.ChromeOptions() # option.add_experimental_option('excludeSwitches', ['enable-automation']) # option.add_experimental_option("detach", True) #

# driver = webdriver.Chrome(options=option) # # driver.get('https://www.baidu.com')

# selenium打开的浏览器navigator.webdriver属性为true

# 把navigator.webdriver属性改为false # script = 'Object.defineProperty(navigator, "webdriver", {get: () => false,});' # driver.execute_script(script)

option = webdriver.ChromeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) option.add_experimental_option("detach", True)

driver = webdriver.Chrome(options=option)

driver.get('http://www.porters.vip/features/webdriver.html')

driver.execute_script('Object.defineProperty(navigator, "webdriver", {get: () => false,});')

driver.find_element(By.XPATH,'//button[@class="btn btn-primary btn-lg"]').click()

selenium常用的js操作

(94条消息) selenium中常用的js操作_weixin_46583017的博客-CSDN博客Python爬虫编程6——seleniumhttps://blog.csdn.net/weixin_46583017/article/details/113738948?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164515283116780269839445%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164515283116780269839445&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-1-113738948.first_rank_v2_pc_rank_v29&utm_term=selenium%E7%9A%84js%E6%93%8D%E4%BD%9C&spm=1018.2226.3001.4187

二.图形验证码识别

Tesseract安装以及操作

阻碍我们爬虫的。有时候正是在登录或者请求一些数据时候的图形验证码。因此这里我们讲解一种能将图片翻译成文字的技术。将图片翻译成文字一般被称为光学文字识别(Optical Character Recognition),简写为OCR。实现OCR的库不是很多,特别是开源的。因为这块存在一定的技术壁垒(需要大量的数据、算法、机器学习、深度学习知识等),并且如果做好了具有很高的商业价值。因此开源的比较少。这里介绍一个比较优秀的图像识别开源库:Tesseract。

  • Tesseract是一个将图像翻译成文字的OCR(光学文字识别,Optical Character Recognition),目前由谷歌赞助。Tesseract是目前公认最优秀、最准确的开源OCR库。Tesseract具有很高的识别度,也具有很高的灵活性,他可以通过训练识别任何字体
  • Windows系统安装 在以下链接下载可执行文件,https://github.com/tesseract-ocr/

在python中安装:pip install pytesseract

设置环境变量:

安装完成后,如果想要在命令行中使用Tesseract,那么应该设置环境变量。Mac和Linux在安装的时候就默认已经设置好了。在Windows下把tesseract.exe所在的路径添加到PATH环境变量中。

识别中文图像,需要下载语言安装包:

URL地址:https://github.com/tesseract-ocr/tessdat

# 命令行使用 # tesseract –help 查看帮助 # tesseract –list-langs 查看可识别的语言 # tesseract 图片名称 返回的文件名 识别前需要先cd到图片的目录 # tesseract 图片名称 返回的文件名 -l 需要识别的语言

在python中使用:

# 在python中使用tesseract识别图片 需要下载两个库 # 1 pip install pytesseract 用来操作 tesseract # 2 pip install pillow 用于处理图片

# 导包 # 1 import pytesseract # 2 from PIL import Image

import pytesseract from PIL import Image import urllib.request

# 打开图片 aaa = Image.open('aaa.png')

# 把图片识别成文字 result_aaa = pytesseract.image_to_string(aaa)

print(result_aaa)

bbb = Image.open('bbb.png')

# image_to_string(bbb,lang='chi_sim') 设置识别的语言 chi_sim(简体中文) result_bbb = pytesseract.image_to_string(bbb,lang='chi_sim')

print(result_bbb)

# 验证码网址 url = 'https://passport.lagou.com/vcode/create?from=register&refresh=1513081451891'

# 保存图片 urllib.request.urlretrieve(网址,'图片名称') # urllib.request.urlretrieve(url,'ccc.png')

ccc = Image.open('ccc.png')

result_ccc = pytesseract.image_to_string(ccc)

print(result_ccc)

云打码平台的使用

由于tesseract对于一些高级的验证并无法做到准确,所以我们可以使用在线打码平台,这里推荐一个打码平台:超级鹰。网址:超级鹰验证码识别-专业的验证码云端识别服务,让验证码识别更快速、更准确、更强大 (chaojiying.com)Python爬虫编程6——seleniumhttps://www.chaojiying.com/

在超级鹰里面可以选择下载python的使用文档说明:

#!/usr/bin/env python # coding:utf-8

import requests from hashlib import md5

class Chaojiying_Client(object):

def __init__(self, username, password, soft_id): self.username = username password = password.encode('utf8') self.password = md5(password).hexdigest() self.soft_id = soft_id self.base_params = { 'user': self.username, 'pass2': self.password, 'softid': self.soft_id, } self.headers = { 'Connection': 'Keep-Alive', 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)', }

def PostPic(self, im, codetype): """ im: 图片字节 codetype: 题目类型 参考 http://www.chaojiying.com/price.html """ params = { 'codetype': codetype, } params.update(self.base_params) files = {'userfile': ('ccc.jpg', im)} r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers) return r.json()

def ReportError(self, im_id): """ im_id:报错题目的图片ID """ params = { 'id': im_id, } params.update(self.base_params) r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers) return r.json()

if __name__ == '__main__': chaojiying = Chaojiying_Client('用户名', '密码', '手动生成的软件id') #用户中心>>软件ID 生成一个替换 96001 # 打开图片 im = open('ccc.png', 'rb').read() # print(chaojiying.PostPic(图片, 识别验证码的类型)) print(chaojiying.PostPic(im, 1902)) #1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()

这里我们在使用的时候,直接调用即可使用方式如下:

注意我们不需要额外在下载其他的库,直接导入chaojiying这个包即可,有的时候导入包的时候会报错,不必理会,没有影响,只要我们将用户名,密码,id输入正确即可。

# 不影响使用 from chaojiying import Chaojiying_Client

# Chaojiying_Client('用户名', '用户密码', '手动生成的软件id') 创建对象 chaojiying = Chaojiying_Client('用户名', '密码', '手动生成的软件id')

# 打开图片 im = open('ddd.png', 'rb').read() # print(chaojiying.PostPic(图片, 识别验证码的类型))

# chaojiying.PostPic(图片, 类型) print(chaojiying.PostPic(im, 9004))

神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试

相关文章:

版权声明:Python教程2022-10-28发表,共计14608字。
新手QQ群:570568346,欢迎进群讨论 Python51学习