【问题标题】:Web Scraper for dynamic forms in python用于python中动态表单的Web Scraper
【发布时间】:2015-08-16 21:56:39
【问题描述】:

我正在尝试填写本网站的表格http://www.marutisuzuki.com/Maruti-Price.aspx

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

我熟悉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})

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

有人可以建议我如何为不同的模型、州和城市提交此表格吗?任何有关如何解决此问题的链接将不胜感激。 python 中有关如何提交表单的示例代码将很有帮助。提前致谢。

【问题讨论】:

    标签: python web-scraping web-crawler mechanize


    【解决方案1】:

    我在教程中遇到了同样的问题,这对我有用:

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

    【讨论】:

      【解决方案2】:

      如果您在开发者工具中查看发送到该站点的请求,您会发现只要您选择了一个状态,就会发送一个 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])
      

      【讨论】:

      • 我需要选择一个特定的车型。然后遍历所有可能的州及其对应的城市。我试图选择选项,但它给了我一个无类型错误。你能帮帮我吗?
      • 我更新了代码以遍历州和每个州的城市。
      猜你喜欢
      • 2021-10-29
      • 1970-01-01
      • 2021-10-19
      • 2018-12-11
      • 1970-01-01
      • 2011-01-08
      • 2019-04-05
      • 1970-01-01
      • 2015-02-26
      相关资源
      最近更新 更多