playWright事件监听的妙用

事件监听

playwright的page对象提供了一个on方法,可以用来监听页面中发生的各个事件,比如close,console,load,request, response等。

看到response没,就是它,如果你爬取的网站数据都是通过ajax响应的,而对应的ajax请求中有加密参数却又解不开时,那你用这个就对了。

response时间可以在每次网络请求得到相应的时候触发,我们可以设置方法获取到对应的response的全部信息。

基础版

1
2
3
4
5
6
7
8
9
10
11
12
13
from playwright.sync_api import sync_playwright

def on_response(response):
    # 监听所有响应的状态码和链接
    print(f'Statue {response.status}: {response.url}')

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.on('response', on_response)
    page.goto('https://spa6.scrape.center/')
    page.wait_for_load_state('networkidle')
    browser.close()

执行便发现我们拿到了该页面加载的所有资源。

升级版

我们发现大多数是无用的,我们只想要拿到指定的ajax响应,那也很好办,比如加载所有电影的ajax链接url包含:/api/movie/,那我们就过滤下这个响应就好了,并且可以通过json()获取到响应的json结果。这样不就可以对这批数据进行入库了?

1
2
3
4
5
6
7
8
9
10
11
12
13
from playwright.sync_api import sync_playwright

def on_response(response):
    if '/api/movie/' in response.url and response.status == 200:
        print(response.json())

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.on('response', on_response)
    page.goto('https://spa6.scrape.center/')
    page.wait_for_load_state('networkidle')
    browser.close()

进阶版

通常我们爬取的url不止一个,url肯定是动态的,page.on(‘response’, on_response)这样传给回调函数函数只能拿到响应,却不知道是哪个url请求来的,我们想在拿到响应的时候同时能接收到其他的动态参数该如何办呢?

答对了,我们使用匿名函数转发下既可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from playwright.sync_api import sync_playwright

def on_response(response, url):
    if '/api/movie/' in response.url and response.status == 200:
        print("%s得到的响应为:" %url, response.json())

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    url = 'https://spa6.scrape.center/'
    page.on('response', lambda response: on_response(response, url))
    page.goto(url)
    page.wait_for_load_state('networkidle')
    browser.close()

以上不是将参数成功传进去了吗,这样入库时特别是有关联表的时候就能做到一个很好地关联呢。

下拉加载

这个纯粹是题外话,只是简单记录下。

如项目中有以下场景:数据是通过下拉滚动条ajax动态加载的数据,那么问题来了,如果页面较大或者网络不好使,你的下拉根本没有生效,一直处于原地下拉的状态,数据没有被成功请求出来,表现形式为状态一直处于“加载中……”,总不能因为这个一直等着吧。

我这里采取的方式为获取数据项的总数,连续执行了5次页面下拉动作数据项的总数都一样,则证明卡这儿了,就跳过该页面爬取下一个页面了,分析来看里面还是存在一个小的算法的。

首先我们存取最近5次的数据项总数;其次判断5次全部一致才证明卡住了。我们这里相当于模拟了一下队列,先进先出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
items_list = []
while True:
    # 判断最近5次拉取到的数据项总数一致,则证明卡了,直接跳过下拉,直接其他操作
    if len(set(items_list))==1:
        return
    # 这里伪代码,用于获取本次下拉获取的数据项总数
    item_sum = get(items)
    # 超过5次,则删除最早的一次数据项总数
    if len(items_list)>4:
        items_list.pop()
    # 将最近一次获取的数据项总数添加到列表中第一个
    items_list.insert(0, item_sum)
    # 伪代码:模拟下拉动作
    scroll_down()

您有什么更好的解决方案,欢迎指教。

引用于:

playWright事件监听的妙用 | 点点网站开发技术分享

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值