【问题标题】:Alternatives to Selenium/Webdriver for filling in fields when scraping headlessly with Python?使用 Python 无头抓取时填充字段的 Selenium/Webdriver 的替代品?
【发布时间】:2016-05-10 15:33:42
【问题描述】:

在 Python 2.7 中,我使用 urllib2 进行抓取,当需要一些 Xpath 时,也使用 lxml。它快速,而且因为我很少需要浏览网站,所以这种组合效果很好。但有时,通常当我到达一个仅在填写简短表单并单击提交按钮 (example) 时才会显示一些有价值数据的页面时,使用 urllib2 的仅抓取方法是不够的。

每次遇到这样的页面时,我都可以调用selenium.webdriver 来重新获取页面并进行表单填写和点击,但这会大大减慢速度。

注意: 这个问题不是关于 urllib2 的优点或局限性,我知道已经有很多讨论。相反,它只专注于寻找一种快速、无头的方法来填写表单等(如果需要,它还允许 XPath 查询)。

【问题讨论】:

    标签: python python-2.7 web-scraping screen-scraping urllib2


    【解决方案1】:

    您可以考虑使用以下几种方法:

    【讨论】:

      【解决方案2】:

      除了alecxe mentioned 之外,另一种选择是使用 GUI 浏览器工具,例如 Firefox 的 Web 控制台 检查单击提交按钮时发出的 POST。有时你 可以找到 POST 数据并简单地对其进行欺骗。例如,使用示例 你发布的网址,如果你

      • 使用火狐浏览http://apply.ovoenergycareers.co.uk/vacancies/#results
      • 单击工具 > Web 开发人员 > Web 控制台
      • 单击网络 > 记录请求和响应正文
      • 填写表格,点击搜索
      • 左键单击 Web 控制台中的(第一个)POST
      • 右键单击(第一个)POST,选择 COPY POST Data
      • 在文本编辑器中粘贴 POST 数据

      你会得到类似的东西

      all
      field_36[]=73
      field_37[]=76
      field_32[]=82
      submit=Search
      

      (请注意,Web 控制台菜单会根据您的 Firefox 版本而有所不同,因此是 YMMV。)然后您可以使用以下代码来欺骗 POST:

      import urllib2
      import urllib
      import lxml.html as LH
      
      url = "http://apply.ovoenergycareers.co.uk/vacancies/#results"
      params = urllib.urlencode([('field_36[]', 73), ('field_37[]', 76), ('field_32[]', 82)])
      response = urllib2.urlopen(url, params)
      content = response.read()
      root = LH.fromstring(content)
      print('\n'.join([tag.text_content() for tag in root.xpath('//dl')]))
      

      产生

        Regulatory Data Analyst
                Contract Type
                  Permanent
                          Contract Hours
                  Full-time
                          Location
                  Bristol
                          Department
                  Business Intelligence
                          Full description
      

      如果您检查 HTML 并搜索 field_36[],您会发现

      <div class="multiwrapper">
      <p class="sidenote multi">(Hold the ctrl (pc) or cmd (Mac) keys for multi-selects) </p>
      <select class="select-long" multiple size="5" name="field_36[]" id="field_36"><option value="0">- select all -</option>
      <option selected value="73" title="Permanent">Permanent</option>
      <option value="74" title="Temporary">Temporary</option>
      <option value="75" title="Fixed-term">Fixed-term</option>
      <option value="81" title="Intern">Intern</option></select>
      </div>
      

      从中很容易推测field_36[]控制Contract Type,值73对应“永久”,74对应“临时”等。同样你可以找出@的选项987654332@、field_32[]all(可以是任何搜索词字符串)。如果你对 HTML 有很好的理解,你甚至可能不需要浏览器工具来构建 POST。

      【讨论】:

      • 这就是我所说的详细程度,很棒的贡献!
      • 确实很棒的贡献。我的爬虫会遇到很多这样的网站,它不会知道它们是基于表单的,直到它确定它们是基于表单的。所以我想我将不得不采用机械化的表单填写/点击方法,除非我能找到另一种可靠地确定每次提交时到达的最终 URL 的方法。
      猜你喜欢
      • 1970-01-01
      • 2015-06-22
      • 2014-02-22
      • 1970-01-01
      • 1970-01-01
      • 2022-08-04
      • 2012-03-19
      • 1970-01-01
      • 2020-08-01
      相关资源
      最近更新 更多