繁体   English   中英

Web Scraper用于python中的动态表单

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM