当使用 Python 无头地抓取时,Selenium/Webdriver 的替代方法用于填充字段?
Alternatives to Selenium/Webdriver for filling in fields when scraping headlessly with Python?
使用 Python 2.7 我正在使用 urllib2 进行抓取,当需要一些 Xpath 时,lxml 也是如此。它是 fast,而且因为我很少需要在网站上导航,所以这种组合效果很好。但有时,通常当我到达一个页面时,该页面只会在填写简短表格并单击提交按钮时显示一些有价值的数据(example),仅使用 urllib2 进行抓取的方法是不够的。
每次遇到这样的页面时,我都可以调用 selenium.webdriver
来重新获取页面并进行表单填写和单击,但这会大大降低速度。
注意: 这个问题不是关于 urllib2 的优点或局限性,我知道关于它已经有很多讨论。相反,它只专注于寻找一种快速、无头的方法来填写表单等(如果需要,它还允许 XPath 查询)。
您可以考虑使用以下几种方法:
mechanize
robobrowser
selenium
使用无头浏览器,例如 PhantomJS
, for example, or using a regular browser, but in a Virtual Display
除了之外,另一种方法是使用 GUI 浏览器工具,例如 Firefox 的 Web Console
检查单击提交按钮时生成的 POST。有时候你
可以找到 POST 数据并简单地欺骗它。例如,使用示例
url 你发布了,如果你
- 使用 Firefox 转到 http://apply.ovoenergycareers.co.uk/vacancies/#results
- 单击工具 > Web 开发人员 > Web 控制台
- 单击“网络”>“记录请求和响应主体”
- 填写表格,点击搜索
- 左键单击 Web 控制台中的(第一个)POST
- 右键单击(第一个)POST,select复制POST数据
- 在文本编辑器中粘贴 POST 数据
你会得到类似
的东西
all
field_36[]=73
field_37[]=76
field_32[]=82
submit=Search
(请注意,Web 控制台菜单会因您的 Firefox 版本而有所不同,因此 YMMV。)然后您可以使用以下代码来欺骗 POST:
import urllib2
import urllib
import lxml.html as LH
url = "http://apply.ovoenergycareers.co.uk/vacancies/#results"
params = urllib.urlencode([('field_36[]', 73), ('field_37[]', 76), ('field_32[]', 82)])
response = urllib2.urlopen(url, params)
content = response.read()
root = LH.fromstring(content)
print('\n'.join([tag.text_content() for tag in root.xpath('//dl')]))
产生
Regulatory Data Analyst
Contract Type
Permanent
Contract Hours
Full-time
Location
Bristol
Department
Business Intelligence
Full description
如果您检查 HTML 并搜索 field_36[]
,您会发现
<div class="multiwrapper">
<p class="sidenote multi">(Hold the ctrl (pc) or cmd (Mac) keys for multi-selects) </p>
<select class="select-long" multiple size="5" name="field_36[]" id="field_36"><option value="0">- select all -</option>
<option selected value="73" title="Permanent">Permanent</option>
<option value="74" title="Temporary">Temporary</option>
<option value="75" title="Fixed-term">Fixed-term</option>
<option value="81" title="Intern">Intern</option></select>
</div>
由此不难推测field_36[]
控制Contract Type
,值73
对应"Permanent",74
对应"Temporary",等等。同样,您可以找出 field_37[]
、field_32[]
和 all
的选项(可以是任何搜索词字符串)。如果你对HTML有很好的理解,你可能甚至不需要浏览器工具来构造POST。
使用 Python 2.7 我正在使用 urllib2 进行抓取,当需要一些 Xpath 时,lxml 也是如此。它是 fast,而且因为我很少需要在网站上导航,所以这种组合效果很好。但有时,通常当我到达一个页面时,该页面只会在填写简短表格并单击提交按钮时显示一些有价值的数据(example),仅使用 urllib2 进行抓取的方法是不够的。
每次遇到这样的页面时,我都可以调用 selenium.webdriver
来重新获取页面并进行表单填写和单击,但这会大大降低速度。
注意: 这个问题不是关于 urllib2 的优点或局限性,我知道关于它已经有很多讨论。相反,它只专注于寻找一种快速、无头的方法来填写表单等(如果需要,它还允许 XPath 查询)。
您可以考虑使用以下几种方法:
mechanize
robobrowser
selenium
使用无头浏览器,例如PhantomJS
, for example, or using a regular browser, but in a Virtual Display
除了
- 使用 Firefox 转到 http://apply.ovoenergycareers.co.uk/vacancies/#results
- 单击工具 > Web 开发人员 > Web 控制台
- 单击“网络”>“记录请求和响应主体”
- 填写表格,点击搜索
- 左键单击 Web 控制台中的(第一个)POST
- 右键单击(第一个)POST,select复制POST数据
- 在文本编辑器中粘贴 POST 数据
你会得到类似
的东西all
field_36[]=73
field_37[]=76
field_32[]=82
submit=Search
(请注意,Web 控制台菜单会因您的 Firefox 版本而有所不同,因此 YMMV。)然后您可以使用以下代码来欺骗 POST:
import urllib2
import urllib
import lxml.html as LH
url = "http://apply.ovoenergycareers.co.uk/vacancies/#results"
params = urllib.urlencode([('field_36[]', 73), ('field_37[]', 76), ('field_32[]', 82)])
response = urllib2.urlopen(url, params)
content = response.read()
root = LH.fromstring(content)
print('\n'.join([tag.text_content() for tag in root.xpath('//dl')]))
产生
Regulatory Data Analyst
Contract Type
Permanent
Contract Hours
Full-time
Location
Bristol
Department
Business Intelligence
Full description
如果您检查 HTML 并搜索 field_36[]
,您会发现
<div class="multiwrapper">
<p class="sidenote multi">(Hold the ctrl (pc) or cmd (Mac) keys for multi-selects) </p>
<select class="select-long" multiple size="5" name="field_36[]" id="field_36"><option value="0">- select all -</option>
<option selected value="73" title="Permanent">Permanent</option>
<option value="74" title="Temporary">Temporary</option>
<option value="75" title="Fixed-term">Fixed-term</option>
<option value="81" title="Intern">Intern</option></select>
</div>
由此不难推测field_36[]
控制Contract Type
,值73
对应"Permanent",74
对应"Temporary",等等。同样,您可以找出 field_37[]
、field_32[]
和 all
的选项(可以是任何搜索词字符串)。如果你对HTML有很好的理解,你可能甚至不需要浏览器工具来构造POST。