如何使用scrapy爬网蜘蛛在SgmlLinkExtractor中的"允许"规则中包含起始URL

use*_*961 7 web-crawler scrapy

我搜索了很多主题,但似乎没有找到我的具体问题的答案.我为网站创建了一个爬行蜘蛛,它运行得很好.然后我做了一个类似的网站爬行类似的网站,但这次我有一个小问题.下到业务:

我的开始网址如下:www.example.com.该页面包含我想要应用我的蜘蛛的链接:

  • www.example.com/locationA
  • www.example.com/locationB
  • www.example.com/locationC

...

我现在有一个问题:每当我输入开始网址时,它会自动重定向到www.example.com/locationA,所有链接我的蜘蛛工作包括

  • www.example.com/locationB
  • www.example.com/locationC ...

所以我的问题是我如何在返回的URL中包含www.example.com/locationA.我甚至得到了如下日志信息:

-2011-11-28 21:25:33 + 1300 [example.com] DEBUG:从http://www.example.com/重定向(302)

-2011-11-28 21:25:34 + 1300 [example.com] DEBUG:重定向(302)为(referer:None)

  • 2011-11-28 21:25:37 + 1300 [example.com] DEBUG:重定向(302)为(referer:www.example.com/locationB)

从parse_item打印出来:www.example.com/locationB

....

我认为这个问题可能与此有关(参考文献:无).有人可以对此有所了解吗?

我通过将起始网址更改为www.example.com/locationB来缩小此问题的范围.由于所有页面都包含所有位置的列表,这次我得到了我的蜘蛛工作:

-www.example.com/locationA

-www.example.com/locationC ...

在一个坚果shell中,我正在寻找方法来包含与开始URL相同(或被重定向)的url到parse_item回调将在其中工作的列表中.

min*_*ast 14

对于其他人有同样的问题,经过大量的搜索,你需要做的就是将你的回调函数命名为parse_start_url.

例如:

rules = (
        Rule(LinkExtractor(allow=(), restrict_xpaths=(
            '//*[contains(concat( " ", @class, " " ), concat( " ", "pagination-next", " " ))]//a',)), callback="parse_start_url", follow=True),
    )
Run Code Online (Sandbox Code Playgroud)


rec*_*dev 1

起初我认为有一个简单的解决方案,使用start_requests()如下:

def start_requests(self):
    yield Request('START_URL_HERE', callback=self.parse_item)    
Run Code Online (Sandbox Code Playgroud)

但测试表明,当start_requests()使用 代替start_urls列表时,蜘蛛会忽略rules,因为CrawlSpider.parse(response)没有被调用。

所以,这是我的解决方案:

import itertools
class SomeSpider(CrawlSpider):
    ....
    start_urls = ('YOUR_START_URL',)
    rules = (
        Rule(
            SgmlLinkExtractor(allow=(r'YOUR_REGEXP',),),
            follow=True,
            callback='parse_item'),
        ),
    )
    def parse(self, response):
        return itertools.chain(
                     CrawlSpider.parse(self, response), 
                     self.parse_item(response))

    def parse_item(self, response):
        yield item
Run Code Online (Sandbox Code Playgroud)

也许有更好的方法。