Pyppeteer简介
Pyppeteer是一个比selenium更加高效的一个爬虫模块,是基于python新特性async实现的,所以它的一些执行也支持异步操作,效率相对于 Selenium 来说也提高了。
快速上手
爬取http://quotes.toscrape.com/js/ 全部页面数据
import asyncio
from pyppeteer import launch
from lxml import etree
#创建一个特殊的函数
async def main():
#对应的pyppeteer相关的操作要写在特殊函数内部
#1.创建一个浏览器对象
bro = await launch(headless=True)
#2.创建一个新的page
page = await bro.newPage()
#3.发起请求
await page.goto('http://quotes.toscrape.com/js/')
#4.获取页面源码数据
page_text = await page.content()
#5.数据解析
tree = etree.HTML(page_text)
div_list = tree.xpath('//div[@class="quote"]')
print(len(div_list))
await asyncio.sleep(3)
await bro.close()
#创建一个协程对象
c = main()
#创建且启动事件循环对象
loop = asyncio.get_event_loop()
loop.run_until_complete(c)
页面显示问题处理
async def main():
…………
await page.setViewport({'width': width, 'height': height})
…………
规避检测:执行js程序执行指定的js程序
async def main():
#规避检测
browser = await launch(headless=False, args=['--disable-infobars'])
节点交互(更好地模拟人地行为)
# 节点交互
await page.type('#kw', '周杰伦', {'delay': 1000}) #是ID,.是class
await asyncio.sleep(3)
#点击搜索按钮
await page.click('#su')
await asyncio.sleep(3)
# 使用选择器选中标签进行点击
alist = await page.querySelectorAll('.s_tab_inner > a')
a = alist[3]
await a.click()
await asyncio.sleep(3)
await browser.close()
asyncio.get_event_loop().run_until_complete(main())
滑动验证
async def get_track():
#输入缺口图片
background = cv2.imread("background.png", 0)
#输入滑块图片
gap = cv2.imread("gap.png", 0)
res = cv2.matchTemplate(background, gap, cv2.TM_CCOEFF_NORMED)
value = cv2.minMaxLoc(res)[2][0]
#value * 278 / 360进行转换,13可以根据实际情况调
return value * 278 / 360 - 13
代码演示
# page.Jeval(selector,pageFunction)#定位元素,并调用js函数去执行
#=>表示js的箭头函数:el = function(el){return el.src}
img_src = await page.Jeval(".JDJRV-bigimg > img", "el=>el.src")
temp_src = await page.Jeval(".JDJRV-smallimg > img", "el=>el.src")
request.urlretrieve(img_src, "background.png")
request.urlretrieve(temp_src, "gap.png")
# 获取gap的距离
distance = await get_track()
"""
# Pyppeteer 三种解析方式
Page.querySelector() # 选择器
Page.querySelectorAll()
Page.xpath() # xpath 表达式
# 简写方式为:
Page.J(), Page.JJ(), and Page.Jx()
"""
#定位到滑动按钮标签
el = await page.J("div.JDJRV-slide-btn")
# 获取元素的边界框,包含x,y坐标
box = await el.boundingBox()
#box={'x': 86, 'y': 34, 'width': 55.0, 'height': 55.0}
#将鼠标悬停/一定到指定标签位置
await page.hover("div.JDJRV-slide-btn")
#按下鼠标
await page.mouse.down()
#模拟人的行为进行滑动
# steps 是指分成几步来完成,steps越大,滑动速度越慢
#move(x,y)表示将鼠标移动到xy坐标位置
#random.uniform生成指定范围的随机浮点数
await page.mouse.move(box["x"] + distance + random.uniform(20, 40),
box["y"],
{"steps": 100})
await page.waitFor(1000)
await page.mouse.up()
await page.waitFor(2000)