【问题标题】:How can I crawl the two level website with scrapy framework如何用scrapy框架爬取二级网站
【发布时间】:2017-01-15 12:15:48
【问题描述】:

我想抓取一个有两级url的网站,第一级是多页列表,url如下:

这样的页面布局:

  • 列表项链接 1
  • 列表项链接 2
  • 列表项链接 3
  • 列表项链接 4

1,2,3,4,5 ...下一页

第二层是详情页,url如下:

我的蜘蛛代码是:

import scrapy
from scrapy.spiders.crawl import CrawlSpider
from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor
from scrapy.spiders.crawl import Rule
from urlparse import urljoin

class MyCrawler(CrawlSpider):
    name = "AnjukeCrawler"

    start_urls=[
        "http://www.example.com/group/"
    ]

    rules = [
        Rule(LxmlLinkExtractor(allow=(),
                               restrict_xpaths=(["//div[@class='multi-   page']/a[@class='aNxt']"])),
                               callback='parse_list_page',
                               follow=True)
    ]

    def parse_list_page(self, response):

        list_page=response.xpath("//div[@class='li-  itemmod']/div/h3/a/@href").extract()

        for item in list_page:
            yield scrapy.http.Request(self,url=urljoin(response.url,item),callback=self.parse_detail_page)


    def parse_detail_page(self,response):

        community_name=response.xpath("//dl[@class='comm-l-detail float-l']/dd")[0].extract()

        self.log(community_name,2)  

我的问题是:我的 parse_detail_page 似乎从未运行过,有人可以告诉我为什么吗?我该如何解决?

谢谢!

【问题讨论】:

  • 您确定您的 xpath 查询会生成结果吗?您可以使用print获取项目列表。
  • 是的,我已经调试了代码,请求已经创建
  • @hl79-james 哦,你能发布爬取日志吗?您可以通过scrapy crawl myspider &> output.log 生成一个。您的请求很可能被欺骗过滤器过滤。

标签: python scrapy


【解决方案1】:

如果我理解您的问题,那么您在这里寻找的是请求链接。请求链接是指您通过请求将从 response1 收集的数据传递到 response2:

def parse(self, response):
    item = dict()
    item['name'] = response.xpath("...").extract_first()

    urls = response.xpath("//a/@href").extract()
    for url in urls:
        yield Request(url, self.parse2,
                      meta={'item':item})  # <-- this is the important bit

def prase2(self, response):
    # now lets retrieve our item generated in parse()
    item = response.meta['item']
    item['last_name'] = response.xpath("...").extract_first()
    return item
    # {'name': 'some_name', 'last_name': 'some_last_name'}

【讨论】:

    【解决方案2】:

    您永远不应该覆盖CrawlSpiderparse 方法,因为它包含此类蜘蛛的核心解析逻辑,因此您的def parse( 应该是def parse_list_page( - 这个错字是您的问题。

    但是,由于同时使用回调和 follow=True 来提取链接,因此您的规则看起来像开销,最好考虑使用规则列表并像这样重写您的蜘蛛:

    class MyCrawler(CrawlSpider):
        name = "AnjukeCrawler"
    
        start_urls = [
            "http://www.example.com/group/"
        ]
    
        rules = [
            Rule(LxmlLinkExtractor(restrict_xpaths="//div[@class='multi-page']/a[@class='aNxt']"),
                 follow=True),
            Rule(LxmlLinkExtractor(restrict_xpaths="//div[@class='li-itemmod']/div/h3/a/@href"),
                 callback='parse_detail_page'),
        ]
    
        def parse_detail_page(self, response):
            community_name = response.xpath("//dl[@class='comm-l-detail float-l']/dd")[0].extract()
            self.log(community_name, 2)
    

    顺便说一句,链接提取器中的括号太多:restrict_xpaths=(["//div[@class='multi- page']/a[@class='aNxt']"])

    【讨论】:

      猜你喜欢
      • 2018-05-05
      • 2017-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多