Scrapy无法爬取所有页面

3

这是我的工作代码:

from scrapy.item import Item, Field

class Test2Item(Item):
    title = Field()

from scrapy.http import Request
from scrapy.conf import settings
from scrapy.selector import HtmlXPathSelector
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.contrib.spiders import CrawlSpider, Rule

class Khmer24Spider(CrawlSpider):
    name = 'khmer24'
    allowed_domains = ['www.khmer24.com']
    start_urls = ['http://www.khmer24.com/']
    USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22 AlexaToolbar/alxg-3.1"
    DOWNLOAD_DELAY = 2

    rules = (
        Rule(SgmlLinkExtractor(allow=r'ad/.+/67-\d+\.html'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        hxs = HtmlXPathSelector(response)
        i = Test2Item()
        i['title'] = (hxs.select(('//div[@class="innerbox"]/h1/text()')).extract()[0]).strip(' \t\n\r')
        return i

它只能抓取10或15条记录,而且总是随机的数字!我无法获取所有具有以下模式的页面:http://www.khmer24.com/ad/any-words/67-anynumber.html。我非常怀疑Scrapy由于重复请求而完成了爬虫。他们建议使用dont_filter = True,但我不知道在我的代码中放置它的位置。

我是Scrapy的新手,真的需要帮助。

我不确定这是否相关,但有许多会进行JavaScript重定向的联盟链接。 - dm03514
1个回答

5

1. "他们建议使用 dont_filter = True,但是我不知道在我的代码中应该放在哪里。"

这个参数在BaseSpider中,而CrawlSpider继承自它。(scrapy/spider.py)默认情况下它被设置为True。

2. "它只能抓取10或15条记录。"

原因: 这是因为start_urls不够好。 在这个问题中,蜘蛛从http://www.khmer24.com/开始爬行,并假设它得到了10个要跟随的网址(满足模式)。然后,蜘蛛继续爬行这些10个链接。但是由于这些页面满意的模式很少,蜘蛛得到了很少的要跟随的网址(甚至没有网址),这导致停止爬行。

可能的解决方案: 我上面说的原因只是重申了icecrime的观点。解决方案也是如此。

  • Suggest to use the 'All ads' page as start_urls. (You could also use the home page as start_urls and use the new rules.)

  • New rules:

    rules = (
        # Extract all links and follow links from them 
        # (since no callback means follow=True by default)
        # (If "allow" is not given, it will match all links.)
        Rule(SgmlLinkExtractor()), 
    
        # Extract links matching the "ad/any-words/67-anynumber.html" pattern
        # and parse them with the spider's method parse_item (NOT FOLLOW THEM)
        Rule(SgmlLinkExtractor(allow=r'ad/.+/67-\d+\.html'), callback='parse_item'),
    )
    

参考: SgmlLinkExtractor, CrawlSpider示例


嗨,当我运行这段代码时,它会爬取站点中的每个页面。然而,我希望它仅根据我设置的规则进行爬取。 - Vicheanak
你想爬取整个网站并获取所有与模式匹配的url吗? - JavaNoScript
与模式http://www.khmer24.com/ad/any-words/67-anynumber-or-words.html匹配的URL。 - Vicheanak
你只想爬取与该模式匹配的所有URL,对吧?但是有一个问题,就像我之前所说,如果你没有添加另一个规则,你只会得到一些URL。(因为第一次获取的URL包含很少的符合模式的URL,而蜘蛛会停止,因为它没有要跟随的URL。) - JavaNoScript
我认为你想要做的是解析与模式匹配的URL页面,对吗?在我的解决方案中,蜘蛛将爬行整个网站以获取与模式匹配的每个URL,但不会解析它获取到的每个URL。它只会解析与模式匹配的URL。如果你仍然对这个问题感到困惑,请给我发电子邮件。 - JavaNoScript
+1 你的回答真的帮了我很多。我之前没有意识到当指定回调函数时,follow 的默认行为是不同的。所以我成功解析的每一页都变成了一个死胡同,而不是通往其他相关兄弟页面的路线。 - sheikhjabootie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接