【问题标题】:scrapy crawling just 1 level of a web-sitescrapy 只抓取网站的 1 级
【发布时间】:2012-02-23 03:50:13
【问题描述】:

我正在使用scrapy抓取一个域下的所有网页。

我看到了this 的问题。但是没有解决办法。我的问题似乎与此类似。我的 crawl 命令输出如下所示:

scrapy crawl sjsu2012-02-22 19:41:35-0800 [scrapy] INFO: Scrapy 0.14.1 started (bot: sjsucrawler)
2012-02-22 19:41:35-0800 [scrapy] DEBUG: Enabled extensions: LogStats, TelnetConsole, CloseSpider, WebService, CoreStats, MemoryUsage, SpiderState
2012-02-22 19:41:35-0800 [scrapy] DEBUG: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, RedirectMiddleware, CookiesMiddleware, HttpCompressionMiddleware, ChunkedTransferMiddleware, DownloaderStats
2012-02-22 19:41:35-0800 [scrapy] DEBUG: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware
2012-02-22 19:41:35-0800 [scrapy] DEBUG: Enabled item pipelines: 
2012-02-22 19:41:35-0800 [sjsu] INFO: Spider opened
2012-02-22 19:41:35-0800 [sjsu] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2012-02-22 19:41:35-0800 [scrapy] DEBUG: Telnet console listening on 0.0.0.0:6023
2012-02-22 19:41:35-0800 [scrapy] DEBUG: Web service listening on 0.0.0.0:6080
2012-02-22 19:41:35-0800 [sjsu] DEBUG: Crawled (200) <GET http://cs.sjsu.edu/> (referer: None)
2012-02-22 19:41:35-0800 [sjsu] INFO: Closing spider (finished)
2012-02-22 19:41:35-0800 [sjsu] INFO: Dumping spider stats:
    {'downloader/request_bytes': 198,
     'downloader/request_count': 1,
     'downloader/request_method_count/GET': 1,
     'downloader/response_bytes': 11000,
     'downloader/response_count': 1,
     'downloader/response_status_count/200': 1,
     'finish_reason': 'finished',
     'finish_time': datetime.datetime(2012, 2, 23, 3, 41, 35, 788155),
     'scheduler/memory_enqueued': 1,
     'start_time': datetime.datetime(2012, 2, 23, 3, 41, 35, 379951)}
2012-02-22 19:41:35-0800 [sjsu] INFO: Spider closed (finished)
2012-02-22 19:41:35-0800 [scrapy] INFO: Dumping global stats:
    {'memusage/max': 29663232, 'memusage/startup': 29663232}

这里的问题是爬虫从第一页找到链接,但没有访问它们。这样的爬虫有什么用。

编辑

我的爬虫代码是:

from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector

class SjsuSpider(BaseSpider):
    name = "sjsu"
    allowed_domains = ["sjsu.edu"]
    start_urls = [
        "http://cs.sjsu.edu/"
    ]

    def parse(self, response):
        filename = "sjsupages"
        open(filename, 'wb').write(response.body)

我所有的其他设置都是默认的。

【问题讨论】:

  • 你能显示Spider代码和Rules吗?

标签: python web-crawler scrapy


【解决方案1】:

我认为最好的方法是使用 Crawlspider。因此,您必须将您的代码修改为下面的代码,以便能够从第一页找到所有链接并访问它们:

class SjsuSpider(CrawlSpider):

    name = 'sjsu'
    allowed_domains = ['sjsu.edu']
    start_urls = ['http://cs.sjsu.edu/']
    # allow=() is used to match all links
    rules = [Rule(SgmlLinkExtractor(allow=()), callback='parse_item')]

    def parse_item(self, response):
        x = HtmlXPathSelector(response)

        filename = "sjsupages"
        # open a file to append binary data
        open(filename, 'ab').write(response.body)

如果你想爬取网站中的所有链接(而不仅仅是第一级的链接), 您必须添加一条规则来跟踪每个链接,因此您必须将规则变量更改为 这个:

rules = [
    Rule(SgmlLinkExtractor(allow=()), follow=True),
    Rule(SgmlLinkExtractor(allow=()), callback='parse_item')
]

因此,我已将您的“解析”回调更改为“解析项”:

在编写爬虫规则时,避免使用 parse 作为回调,因为 CrawlSpider 使用 parse 方法本身来实现其逻辑。所以如果你重写 parse 方法,爬虫将不再工作。

有关更多信息,您可以查看:http://doc.scrapy.org/en/0.14/topics/spiders.html#crawlspider

【讨论】:

  • 尝试把callback='parse_item'改成callback=('parse_item'),或者把规则改成这样:rules = [ Rule(SgmlLinkExtractor(allow=()), follow=True,callback =('parse_item') ]
  • 此外,最好在爬虫声明之前打开文件,只调用parse_item中的write方法。您可以在爬虫类之前添加它:myfile = open(filename, 'ab') 并在 parse_item 中使用它:myfile.write(response.body)。在 write 调用之后,您可以使用 flush 函数强制您的程序刷新文件中的数据:myfile.flush()。
  • allow=() 将不起作用,因为 Rule 的内部是在匹配的基础上完成的,即如果您希望处理所有 url,只需输入 Rule(SgmlLinkExtractor(allow=('.+ ',)), 回调='parse_item')。不要忘记逗号,因为它需要一个元组
  • @goh,为了避免错过微妙的逗号/元组,scrapy 代码示例使用列表,例如Rule(SgmlLinkExtractor(allow=['.+']), callback='parse_item')。另外我可以确认@ThanasisPetsas 的答案中的第二条规则不会调用回调,回调必须设置在具有follow=True 的规则中,就像你所做的那样,@goh。但我对编辑答案中的错误代码犹豫不决,因为我是 Scrapy 的新手。
【解决方案2】:

如果你使用basespider,在解析方法/回调中,如果你打算访问这些url,你需要提取你想要的url并返回Request对象。

for url in hxs.select('//a/@href').extract():
            yield Request(url, callback=self.parse)

parse 所做的是将响应返回给您,您必须告诉您您想用它做什么。它在docs 中说明。

或者如果您希望使用 CrawlSpider,那么您只需为您的 spider 定义规则即可。

【讨论】:

  • 谢谢。我可以在文档中看到这一点,但教程没有说明任何内容,并且我认为它会在允许的域下将所有网页爬下树。我还没有测试过。但我一定会让你知道的。再次感谢顺便说一句。
【解决方案3】:

以防万一这有用。当爬虫在这种情况下无法正常工作时,请确保从蜘蛛文件中删除以下代码。这是因为如果在文件中声明了该方法,则蜘蛛默认调用该方法。

def parse(self, response):
  pass

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-23
    相关资源
    最近更新 更多