python中动态表单的Web Scraper

2024-04-27 02:44:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在填写这个网站的表格http://www.marutisuzuki.com/Maruti-Price.aspx。在

它由三个下拉列表组成。第二个是城市,第三个是汽车模型。前两个是静态的,第三个是根据state的值动态生成city,有一个onclick java脚本事件在运行,它获取一个状态中对应城市的值。在

我熟悉python中的mechanize模块。我遇到了几个链接,告诉我我无法处理mechanize中的动态内容。但是“动态添加项”部分中的这个链接http://toddhayton.com/2014/12/08/form-handling-with-mechanize-and-beautifulsoup/声明我可以使用mechanize来处理动态内容,但是我不理解其中的这一行代码

item = Item(br.form.find_control(name='searchAuxCountryID'),{'contents': '3', 'value': '3', 'label': 3})

表单中城市字段对应的这行代码中的“Item”是什么。我遇到了selenium模块,它可以帮助我处理动态下拉列表。但是我没有在它的文档中找到任何关于如何使用它的好博客。在

有人能建议我如何提交不同型号,州和城市的表格吗?任何关于如何解决这个问题的链接将不胜感激。关于如何提交表单的python示例代码将很有帮助。提前谢谢。在


Tags: 模块代码formcomhttp表单内容列表
2条回答

如果您在“开发人员工具”中查看发送到该站点的请求,您将看到在您选择状态后立即发送一个帖子。返回的响应具有填充了city下拉列表中的值的表单。在

因此,要在脚本中复制此内容,您需要如下所示:

  • 打开页面
  • 选择窗体
  • 为“模型”和“状态”选择值
  • 提交表格
  • 从返回的响应中选择表单
  • 为城市选择值(现在应该填充它)
  • 提交表格
  • 分析结果表的响应

看起来像:

#!/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})

相关问题 更多 >