【问题标题】:My Web scraper sporadically fails due to very small difference in URLs由于 URL 的差异很小,我的网络爬虫偶尔会失败
【发布时间】:2016-12-09 01:04:04
【问题描述】:

我正面临这个令人沮丧的问题,它极大地影响了我的数据收集速度。我已经为特定体育网站编写了这个定制的网络scraper,我从一个文件中读取了 URL,然后调用我的 scraper:

import re
from bs4 import BeautifulSoup
import html5lib
import socket
from PassesData import *
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

base: http://www.something.com
with open('Part2-PostIS-0430PM.txt', 'w') as f5:
    with open('URLLinks.txt') as temp:
        for url in temp:
            f5.write(getData(base+url))
            f5.write("\n")

URLLinks.txt 中的示例数据 --> /something/wherein/12345

爬虫可以完美地工作好几个小时,一个接一个地读取 URL,并将其传递给爬虫稀疏化并返回结果,将其写入外部的文本文件中,使用 --> 但是当它读取一个略有不同的 URL 时,例如:

/something/wherein/12345 而不是 /something/wherein/12345,

我的爬虫失败:UnboundLocalError: local variable 'header' referenced before assignment: header 是我从 URL 中稀疏的页眉,例如 header = soup.h1.b.text.strip( ) 并将其传递给 print 函数。它适用于我正在阅读的 99% 的 URL,但是中间的一个 URL 会导致整个过程停止,然后当我将 URL 传递给例如 Google chrome 时,它​​会自动修复丢失的术语并获取正确的术语,例如例如,当我将“http://www.something.com/someting/wherein/12345”传递给 Chrome 时,它​​会毫无问题地打开 /something/wherein/12345。在这里,我去更改 URLlinks.txt 中的那个 URL,然后再次运行我的爬虫,这导致我的数据收集出现巨大延迟。

这造成了巨大的延迟,因为我必须不断地照看这个过程。

我非常感谢任何解决方案。

我正在使用 BeautifulSoup4 和套接字(不使用 URLLIB 和其他方法,因为它们不适用于我正在抓取的网站)

我必须再次强调,我的爬虫可以完美运行,但是对于 URL 的微小变化,例如使用 /this-is-a/link/to/12345 而不是 /this-is/link/to/12345浏览器完全理解但我的代码失败了,即使我首先从同一个网站收集了这些 URL!!!

请帮帮我。感谢社区

【问题讨论】:

  • 您能否举例说明 Chrome 如何自动将 URL 的“someting”更改为“something”?这似乎不太可能
  • Give chrome this: stackoverflow.com//questions/41051497/… insted of : stackoverflow.com//questions/41051497/… 请注意由于非常小的细微差别 --> 由于非常小 DNS 服务器会自动找到您的意思并检索正确的内容,但是使用我上面提供的代码时,即使是很小的错误也不能原谅。
  • 与DNS服务器无关。它是 stackoverflow 服务器通过 301 将您的“错误”url 重定向到该问题的官方 url,只要问题 id 正确,您可以为该 url 使用您想要的任何名称,这是 stackoverflow 可以接受的。我想你正在抓取的网站做同样的事情。您也可以查看我关于使用requests 完成这项工作的答案。

标签: python-2.7 url web-scraping beautifulsoup web-crawler


【解决方案1】:

您可以使用网络抓取框架scrapy,我认为它也会因 URL 不正确而失败,但它不会停止该过程,因此其他请求仍然有效。它也是异步的,因此您的请求将得到独立且更快的处理。

【讨论】:

    【解决方案2】:

    实际上,我做了一些不能解决问题的事情,但这是次优的事情。它允许我在记录那些有问题的 URL 时继续抓取,以便以后查找它们:我使用的代码如下:

    with open('Part2-PostIS-Datas-7-1159AM.txt', 'w') as f5:
       log = open("LOG-P2-7-1159.txt", 'a')
       with open('Part2-Links-7.txt') as temp:
           for url in temp:
              try:
                  f5.write(getData(base+url))
                  f5.write("\n")
              except (KeyboardInterrupt, SystemExit):
                  raise
              except:
                  print(url, file=log )
                  pass
    

    现在我可以运行我的脚本并一个一个地抓取页面,1% 有问题的 URL 不会停止整个过程。数据收集结束后,我必须查看我的 LOG 文件并修复 URL 并再次运行它们。

    【讨论】:

      【解决方案3】:

      真的不知道你用什么模块来抓取,但在我这边requests 可以与你给我的例子一起工作:

      >>> import requests
      >>> response = requests.get('http://stackoverflow.com//questions/41051497/my-web-scraper-sporadically-due-very-small-difference-in-urls?noredirect=1#comment69311269_41051497')
      >>> response.url
      u'http://stackoverflow.com/questions/41051497/my-web-scraper-sporadically-fails-due-to-very-small-difference-in-urls?noredirect=1'
      >>> response = requests.get('http://stackoverflow.com//questions/41051497/how-wrong-can-the-name-be?noredirect=1')
      >>> response.url
      u'http://stackoverflow.com/questions/41051497/my-web-scraper-sporadically-fails-due-to-very-small-difference-in-urls?noredirect=1'
      

      正如您所看到的,无论您提供什么样的“错误名称”,只要问题编号正确,响应就会执行 301 并根据 stackoverflow 服务器的要求重定向到正确的 url。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多