[英]Web Scraper for dynamic forms in python
我正在尝试填写此网站http://www.marutisuzuki.com/Maruti-Price.aspx的表格。
它由三个下拉列表组成。 一是汽车模型,二是州,三是城市。 前两个是静态的,第三个是city的,它是根据state的值动态生成的,正在运行一个onclick Java脚本事件,该事件获取一个州中相应城市的值。
我熟悉python中的机械化模块。 我遇到了几个链接,这些链接告诉我我无法在机械化中处理动态内容 。 但是,“ 动态添加项目 ”部分中的链接http://toddhayton.com/2014/12/08/form-handling-with-mechanize-and-beautifulsoup/指出,我可以使用机械化来处理动态内容,但是我做到了不明白其中的这一行代码
item = Item(br.form.find_control(name='searchAuxCountryID'),{'contents': '3', 'value': '3', 'label': 3})
此代码行中与表单中的city字段对应的“ Item”是什么。 我遇到了硒模块,它可以帮助我处理动态下拉列表。 但是我无法在其文档中找到任何有关如何使用它的东西。
有人可以建议我如何针对不同的模型,州和城市提交此表格吗? 任何有关如何解决此问题的链接将不胜感激。 python中有关如何提交表单的示例代码将很有帮助。 提前致谢。
如果您在开发人员工具中查看发送到该站点的请求,则将看到在选择状态后立即发送了POST。 发送回的响应具有填写城市下拉列表中的值的形式。
因此,要将其复制到脚本中,您需要以下内容:
看起来像:
#!/usr/bin/env python
import re
import mechanize
from bs4 import BeautifulSoup
def select_form(form):
return form.attrs.get('id', None) == 'form1'
def get_state_items(browser):
browser.select_form(predicate=select_form)
ctl = browser.form.find_control('ctl00$ContentPlaceHolder1$ddlState')
state_items = ctl.get_items()
return state_items[1:]
def get_city_items(browser):
browser.select_form(predicate=select_form)
ctl = browser.form.find_control('ctl00$ContentPlaceHolder1$ddlCity')
city_items = ctl.get_items()
return city_items[1:]
br = mechanize.Browser()
br.open('http://www.marutisuzuki.com/Maruti-Price.aspx')
br.select_form(predicate=select_form)
br.form['ctl00$ContentPlaceHolder1$ddlmodel'] = ['AK'] # model = Maruti Suzuki Alto K10
for state in get_state_items(br):
# 1 - Submit form for state.name to get cities for this state
br.select_form(predicate=select_form)
br.form['ctl00$ContentPlaceHolder1$ddlState'] = [ state.name ]
br.submit()
# 2 - Now the city dropdown is filled for state.name
for city in get_city_items(br):
br.select_form(predicate=select_form)
br.form['ctl00$ContentPlaceHolder1$ddlCity'] = [ city.name ]
br.submit()
s = BeautifulSoup(br.response().read())
t = s.find('table', id='ContentPlaceHolder1_dtDealer')
r = re.compile(r'^ContentPlaceHolder1_dtDealer_lblName_\d+$')
header_printed = False
for p in t.findAll('span', id=r):
tr = p.findParent('tr')
td = tr.findAll('td')
if header_printed is False:
str = '%s, %s' % (city.attrs['label'], state.attrs['label'])
print str
print '-' * len(str)
header_printed = True
print ' '.join(['%s' % x.text.strip() for x in td])
我在本教程中遇到了同样的问题,这对我有用:
item = mechanize.Item(br.form.find_control(name='searchAuxCountryID'),{'contents': '3', 'value': '3', 'label': 3})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.