1. 导语

Selenium 作为浏览器自动化工具,由于其可以直接执行 js 代码的优越性,经常被用做爬虫工具。但是,毕竟需要控制浏览器,低效率高内存始终是其难以甩掉的标签。在我个人爬虫开发中,对如何高效利用 selenium 有了一套个人的理解。

2. 用 js 注入代替 selenium 原生操作

selenium 库提供的 execute_script 方法使 js 注入成为可能。下面是一个 js 注入的例子

1
2
js="document.getElementsByClassName('form-control')[0].value='%s';"%(requestCode[i][0].value)
driver.execute_script(js)

以 selenium 填写表单为例,python 代码如下:

1
2
vorname = driver.find_element_by_name('vorname')
vorname.send_keys('vorname')

使用 selenium 填写表单,执行速度是相当慢的,当 input 标签很多的时候,selenium 会从上到下依次执行表单填写,这就会导致在填写完整的表单时,填写时间其实比人为通过浏览器 autocomplete 快不了多少,甚至更慢。
使用 js 来执行表单填写,如下代码:

1
2
fill_form_script = "bsform.vorname.value='vorname';bsform.submit()"
driver.execute_script(fill_form_script)

bsform 为 form 标签的 name 属性,vorname 为 input 标签的 name 属性,通过 bsform.vorname.value 代码快速填写表单,多个 input 几乎是同时完成,在调用 submit()方法提交表单,甚至可以直接绕过浏览器的表单验证。相比 selenium 模拟操作更快,代码也更加简介。

3. 利用 ajax 代替 selenium 打开多个窗口

我们在使用 selenium 时,最主要还是看重,它直接可以执行网页中的 js,而无需在去分析 js 代码的特点。但是受限于,其高内存占用的缺点,很难在多线程时执行爬虫任务。利用 js 注入可以在网页中执行 js 代码,既然如此,那是否可以注入 js 直接用 ajax 来请求网页,如果可以,相比较于利用 requests 库,这样可以极大的避免被网页服务器的反爬虫机制检测到,也能绕开分析 js 来获取一些参数,甚至 ajax 可以自动的为我们的请求添加 cookie,也避免每次都需要去保存 cookie 的烦恼。。事实上,selenium 为了避免其被滥用,并没有提供 ajax 的拦截功能。也就是说,即便我们通过 js 发起了请求,也不能通过 selenium 直接获取到返回的数据。
对此,可以利用 js 代码,将 ajax 返回的数据渲染到网页中,再通过 selenium 提取网页数据来获取 ajax 返回的数据,获取后再将网页恢复原状。这样相比于,每打开一个网页就打开一个浏览器窗口,对内存的占用就小了很多。。

评论