【问题标题】:CrawlSpider not executing callbackCrawlSpider 不执行回调
【发布时间】:2019-02-06 21:17:39
【问题描述】:

我通过扩展 CrawlSpider 创建了一个蜘蛛。

当蜘蛛运行并找到文章页面时,我想获取作者个人资料的链接并向个人资料页面发出请求并使用 parse_author 对其进行解析,但由于某种原因,此 parse_author 回调永远不会执行。

我的代码:

import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.http.request import Request


class CityamSpider4(CrawlSpider):

    name = "city_am_v4"
    custom_settings = {
        'CONCURRENT_REQUESTS': '1',
    }
    allowed_domains = ['cityam.com']
    start_urls = [
        'http://www.cityam.com',
    ]
    rules = (
        Rule(LinkExtractor(deny=('dev2.cityam.com', 'sponsored-content', )), callback='parse_item'),
    )

    def parse_item(self, response):
        # parse article page
        article_title = response.css('.article-headline h1::text').extract_first(default='null').strip()
        if article_title is not 'null':
            print 'Article url : ' + response.url
            author_url = response.css('.author-container .author-text a.author-name::attr(href)').extract_first(default='null').strip()
            print 'Author link: ' + author_url
            author_url = response.urljoin(author_url)
            print 'Author link: ' + author_url
            yield Request(author_url, callback=self.parse_author)

    def parse_author(self, response):
        # parse author page
        author_name = response.css(".cam-profile-header-title::text").extract_first(default='null').strip()
        print 'Author name: ' + author_name
        yield {
            'name': author_name,
        }

【问题讨论】:

  • 在我看来python版本不会随着时间的推移而回滚,谁用版本2?
  • 只有加莱西奥。也许他是对的。回到 python 2 你会很开心

标签: scrapy web-crawler scrapy-spider


【解决方案1】:

问题在于您的链接提取规则也匹配作者链接,并且 Scrapy 默认会丢弃重复请求,因此您的 parse_item 方法是接收您期望在 parse_author 中的响应的方法。

可能的解决方案包括:

  • 修改您的 LinkExtractor 以不匹配作者 URL。

  • 将作者解析逻辑从 parse_author 移动到 parse_item

  • dont_filter=True 添加到Request,这样即使您产生的请求与您的链接提取器找到的请求重复,也不会被过滤掉。

【讨论】:

    【解决方案2】:

    您在网站页面上使用了错误的端口:

    1. HTTP:80 端口 - 不是
    2. HTTPS:443 端口 -

    您的行 yield Request(url=author_url, callback=self.parse_author) 指的是(例如)http://www.cityam.com/profile/joseph.ray(在端口 80 上)。

    您必须通过 HTTPS 使用请求:https://www.cityam.com/profile/joseph.ray 然后程序执行将继续到方法parse_author

    更改您的请求 URL,每个人都会很高兴。 顺便说一句,我认为编写这样的代码是一种不好的做法:

    print 'Article url : ' + response.url(有些编译器不理解,会报错)

    必须是: print("Article url : " + response.url)

    【讨论】:

    • 这太好了,我浪费了 3 天的培训来弄清楚这一点:) 你能解释一下为什么我需要使用 https 端口,即使该网站可以通过 http 端口访问?再次感谢。
    • 我刚刚用在线扫描仪扫描了所有可能的端口。而且不难猜到这个网站会使用https,因为信息应该受到保护。
    • 未显示:997 个关闭端口 PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 443/tcp open https Nmap done:10.24 秒内扫描了 1 个 IP 地址(1 个主机启动)
    • 您可能已经猜到,使用 HTTPS 的一个关键因素是安全性。它最大限度地防止您的数据在从您的设备到服务器的过程中被盗。
    • 这不是问题。并且关于print 的评论不合适,用户代码显然是 Python 2 并且那些打印语句在 Python 2 中非常好。
    猜你喜欢
    • 1970-01-01
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 2012-09-01
    相关资源
    最近更新 更多