gpt4 book ai didi

python - 需要为将要解析 800 万个页面的高效网络爬虫提供设计建议 - Python

转载 作者:太空宇宙 更新时间:2023-11-03 11:10:06 25 4
gpt4 key购买 nike

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

2年前关闭。




Improve this question




我将开发一个小爬虫,它会从同一个网站上获取很多页面,所有的请求都是更改 url 的 ID 号。

我需要把我解析的所有数据保存成一个csv(没什么特别的),最多我会爬取大约6M-8M的页面,其中大部分不包含我想要的数据,我知道大约有400K我需要解析的页面,它们的结构都相似,我无法避免抓取所有的 url。

这就是我获取数据时页面的外观 - http://pastebin.com/3DYPhPRg

那是我没有得到数据的时候 - http://pastebin.com/YwxXAmih

数据保存在 td 内的跨度中 -

I need the data between ">" and "</span>".

<span id="lblCompanyNumber">520000472</span></td>
<span id="lblCompanyNameHeb">חברת החשמל לישראל בעמ</span></td>
<span id="lblStatus">פעילה</span></td>
<span id="lblCorporationType">חברה ציבורית</span></td>
<span id="lblGovCompanyType">חברה ממשלתית</span></td>
<span id="lblLimitType">מוגבלת</span></td>
etc'

从文档中解析出来并不难。

问题是获取url并解析它们需要几天时间,它会消耗大量内存,我认为它会在这里崩溃,这对我来说非常危险,除非它崩溃它不能再运行了。

我想过——
 - fetching a url (urllib2)
- if there's an error - move next (if it'll happen 5 times - I stop and save errors to log)
- parse the html (still don't know whats best - BeautifulSoup \ lxml \
scrapy \ HTMLParser etc')
- if it's empty (lblCompanyNumber will be empty) save the ID in the emptyCsvFile.csv
- else: save the data to goodResults.csv

问题是——
  • 我应该使用哪些数据类型以提高效率和速度(对于我解析的数据和获取的内容)?
  • 我应该使用哪个 HTML 解析库?也许正则表达式? span id 是固定的,当有数据时不会改变(再次,高效,速度,简单)
  • 保存到文件,保持文件句柄这么长时间等等' - 有没有一种方法可以占用更少的资源并且更有效地保存数据? (至少 40 万行)
  • 我还没有想过和需要处理的其他任何事情,也许还有一些优化技巧:)

  • 我想到的另一个解决方案是使用 wget,将所有页面保存到磁盘,然后删除所有与空文档具有相同 md5sum 的文件,唯一的问题是我没有保存空 ID。

    顺便说一下,我需要使用 py2exe 并用它制作一个 exe,所以像 scrapy 这样的东西在这里很难使用(众所周知,它会导致 py2exe 出现问题)。

    谢谢!

    最佳答案

    我将 httplib2 用于这种事情,因为 Python 标准库例程中应该存在内存泄漏。此外,httplib2 可以配置为保留缓存,如果您必须重新启动和重做某些页面,这可能很有用。

    我只运行了 170 万页加上来自另一台服务器的大约 200000 页,因此我无法评论您期望的数量。

    但是我使用带有主题交换和持久消息队列(delivery_mode=2)的 AMQP 来插入这一切。这将 ny id 输入到使用 httplib2 的 worker 中,并确保检索到每个 id。我使用内存缓存跟踪它们,该内存缓存使用磁盘上的东京暴君哈希表持久化。我能够关闭并重新启动 worker 并在机器之间移动它们而不会丢失任何 ID。在我杀死它以修补它之前,我已经让 worker 一次运行了两个三周。

    另外,我使用 lxml 来解析响应,因为它很快。

    哦,在成功检索和处理页面后,我将 id 作为消息发布到已完成的队列。然后我手动从该队列中复制消息并将其与输入列表进行比较以确保整个过程是可靠的。

    对于 AMQP,我使用 amqplib 和 RabbitMQ 作为代理。现在,我建议您查看 AMQP 的 haigha。尽管它的文档很少,但它的模型严格遵循 AMQP 0.9.1 规范文档,因此您可以使用它们来找出选项等。

    @YSY:我无法剪切和粘贴代码,因为我是在工作中完成的,但这没什么特别的。只是一个带有 try: except: 的循环,包裹在 http 请求中。像这样的东西:

    retries = 5
    while retries > 0:
    requestSucceeded = True # assume the best
    try:
    resp, content = h.request("http://www.example.com/db/1234567")
    if resp is None:
    requestSucceeded = False
    log.warn ("1234567: no http response")
    elif resp.status != 200:
    requestSucceeded = False
    log.warn ("1234567: replied with {0:d}".format(resp.status))
    except Exception as e:
    requestSuceeded = False
    log.warn("1234567: exception - " + str(e))
    if not requestSucceeded:
    time.sleep(30)
    retries -= 1
    else:
    retries = 0
    if requestSucceded:
    process_request()
    ack_message()

    llop 处理两种类型的失败,一种是 HTTP 服务器与我们交谈但不返回回复,另一种是出现异常,可能是网络错误或其他任何事情。您可以更复杂,并以不同的方式处理不同的故障情况。但这通常有效。调整 sleep 时间并重试,直到成功率超过 90%,然后再处理其余的。我相信我现在正在使用半小时 sleep 和 3 次重试,或者可能是 15 分钟的 sleep 。真的不重要。

    完整运行后,我处理结果(日志和已完成消息列表)以确保它们同意,以及任何未能检索到的文档,我在放弃之前再次尝试。当然,如果我能想出办法,我会扫描日志寻找类似的问题并调整我的代码来处理它们。

    或者你可以谷歌“scrapy”。那可能对你有用。就个人而言,我喜欢使用 AMQP 来控制整个过程。

    关于python - 需要为将要解析 800 万个页面的高效网络爬虫提供设计建议 - Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6751306/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com