正常用例
lxml 是一个很棒的库,它为填写和提交表单提供了不错的支持,as documented here。这个特定用例的真正挑战在于表单的工作方式。
区域实验室选择框不是表格的一部分;它的值是用 cookie 提交的。这让事情变得更加困难。
如果不是这种情况,您可以发出GET,从中提取表单,更改您感兴趣的值,提交它,然后检查返回的链接。该脚本可能如下所示:
req = requests.get('http://www.questdiagnostics.com/testcenter/BUSearch.action?submitValue=BUSearch&keyword=Toxoplasma+Abs+IgG+%2F+IgM')
hdoc = lxml.html.fromstring(req.content)
form = hdoc.forms[1]
# Set form inputs using `form.fields = dict(...)`
form.action = "http://www.questdiagnostics.com" + form.action
submitResult = lxml.html.parse(lxml.html.submit_form(form)).getroot()
links = submitResult.xpath('//*[@id="maincolumn"]/ol/li/a[@class="title"]/@href')
虽然您可以在调用 lxml.html.submit_form() 时添加任意请求参数,但我没有看到添加任意 cookie 的方法。
此用例
也就是说,由于此表单本质上是通过重定向回自身来工作的(使用额外的 cookie 来标识实验室),您可以通过将 cookie 添加到初始 GET 来模拟这种行为。您可能根本不需要处理表单提交。此脚本将显示 SKB 实验室的前十个链接:
cookies = dict(TC11SelectedLabCode='SKB')
req = requests.get('http://www.questdiagnostics.com/testcenter/BUSearch.action?submitValue=BUSearch&keyword=Toxoplasma+Abs+IgG+%2F+IgM', cookies=cookies)
hdoc = lxml.html.fromstring(req.content)
links = hdoc.xpath('//*[@id="maincolumn"]/ol/li/a[@class="title"]/@href')
print(links)
您可以更进一步,发出不带 cookie 的 GET 以获取实验室列表,然后遍历该列表,在每个列表上调用 requests.get(),将适当的 TC11SelectedLabCode cookie 发送到模拟表单提交。
备注
请注意,虽然lxml 有不错的表单提交支持,但您实际上并没有点击任何内容。没有什么可以“为 DOM 注入活力”。
页面上的所有 javascript 都没有运行。
为了说明为什么这很重要,请考虑这个例子。如果您想验证结果第 2 页上的链接,我无法说明您将如何完成该操作。如果您的测试需要在页面上运行 javascript,我认为您需要的不仅仅是 requests 和 lxml。