18

我正在用一个非常简单的网络刮刀使用scrapy. 我对scrapy甚至python都很陌生,但设法编写了一个可以完成这项工作的蜘蛛。但是,它真的很慢(爬取 23770 个页面大约需要 28 小时)。

我查看了scrapy网页和邮件列表stackoverflow,但我似乎无法找到编写初学者可以理解的快速爬虫的通用建议。也许我的问题不是蜘蛛本身,而是我运行它的方式。欢迎所有建议!

如果需要,我在下面列出了我的代码。

from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
from scrapy.item import Item, Field
import re

class Sale(Item):
    Adresse = Field()
    Pris = Field()
    Salgsdato = Field()
    SalgsType = Field()
    KvmPris = Field()
    Rum = Field()
    Postnummer = Field()
    Boligtype = Field()
    Kvm = Field()
    Bygget = Field()

class HouseSpider(BaseSpider):
    name = 'House'
    allowed_domains = ["http://boliga.dk/"]
    start_urls = ['http://www.boliga.dk/salg/resultater?so=1&type=Villa&type=Ejerlejlighed&type=R%%C3%%A6kkehus&kom=&amt=&fraPostnr=&tilPostnr=&iPostnr=&gade=&min=&max=&byggetMin=&byggetMax=&minRooms=&maxRooms=&minSize=&maxSize=&minsaledate=1992&maxsaledate=today&kode=&p=%d' %n for n in xrange(1, 23770, 1)]

    def parse(self, response):
        hxs = HtmlXPathSelector(response)
        sites = hxs.select("id('searchresult')/tr")
        items = []      
        for site in sites:
            item = Sale()
            item['Adresse'] = site.select("td[1]/a[1]/text()").extract()
            item['Pris'] = site.select("td[2]/text()").extract()
            item['Salgsdato'] = site.select("td[3]/text()").extract()
            Temp = site.select("td[4]/text()").extract()
            Temp = Temp[0]
            m = re.search('\r\n\t\t\t\t\t(.+?)\r\n\t\t\t\t', Temp)
            if m:
                found = m.group(1)
                item['SalgsType'] = found
            else:
                item['SalgsType'] = Temp
            item['KvmPris'] = site.select("td[5]/text()").extract()
            item['Rum'] = site.select("td[6]/text()").extract()
            item['Postnummer'] = site.select("td[7]/text()").extract()
            item['Boligtype'] = site.select("td[8]/text()").extract()
            item['Kvm'] = site.select("td[9]/text()").extract()
            item['Bygget'] = site.select("td[10]/text()").extract()
            items.append(item)
        return items

谢谢!

4

4 回答 4

37

这里有一系列可以尝试的东西:

  • 使用最新的scrapy版本(如果还没有使用)
  • 检查是否使用了非标准中间件
  • 尝试增加CONCURRENT_REQUESTS_PER_DOMAINCONCURRENT_REQUESTS设置(文档
  • 关闭日志记录LOG_ENABLED = False文档
  • 尝试yield循环中的项目,而不是将项目收集到items列表中并返回它们
  • 使用本地缓存 DNS(请参阅此线程
  • 检查此站点是否正在使用下载阈值并限制您的下载速度(请参阅此线程
  • 在蜘蛛运行期间记录 cpu 和内存使用情况 - 看看那里是否有任何问题
  • 尝试在scrapyd服务下运行相同的蜘蛛
  • 看看grequests + lxml是否会表现得更好(询问您是否需要任何帮助来实施此解决方案)
  • 尝试运行,请参阅在 PyPyScrapy运行 Scrapypypy

希望有帮助。

于 2013-06-10T18:46:56.067 回答
5

Looking at your code, I'd say most of that time is spent in network requests rather than processing the responses. All of the tips @alecxe provides in his answer apply, but I'd suggest the HTTPCACHE_ENABLED setting, since it caches the requests and avoids doing it a second time. It would help on following crawls and even offline development. See more info in the docs: http://doc.scrapy.org/en/latest/topics/downloader-middleware.html#module-scrapy.contrib.downloadermiddleware.httpcache

于 2013-06-10T23:21:25.623 回答
0

我还使用优化的 C# 进行网络抓取,但最终会受到 CPU 限制,所以我改用 C。

解析 HTML 会破坏 CPU 数据缓存,并且很确定您的 CPU 根本没有使用 SSE 4.2,因为您只能使用 C/C++ 访问此功能。

如果你做数学,你很快就会受到计算限制,但不受内存限制。

于 2015-10-18T02:19:54.167 回答
0

加快您的scrapy的一种解决方法是start_urls适当地配置您的。

例如,如果我们的目标数据在http://apps.webofknowledge.com/doc=1文档编号范围从11000,您可以配置您start_urls的以下内容:

 start_urls = [
    "http://apps.webofknowledge.com/doc=250",
    "http://apps.webofknowledge.com/doc=750",
]

这样,请求将同时从250to251,249和 from 750to开始751,749,因此与start_urls = ["http://apps.webofknowledge.com/doc=1"].

于 2018-06-20T10:49:32.380 回答