python - 无法强制 scrapy 使用重定向的 url 进行回调

标签 python python-3.x redirect web-scraping scrapy

我使用 scrapy 创建了一个 python 脚本来抓取某个网页中可用的一些信息。问题是我尝试使用的链接经常被重定向。但是,当我尝试使用请求几次时,我得到了所需的内容。

对于 scrapy,我无法重用该链接,因为我发现无论我尝试多少次它都会重定向。我什至可以使用 response.meta.get("redirect_urls")[0] 捕获主 url,以便在 parse 方法中递归使用。但是,它总是会被重定向,因此回调不会发生。

这是我当前的尝试(脚本中使用的链接只是一个占位符):

import scrapy
from scrapy.crawler import CrawlerProcess

class StackoverflowSpider(scrapy.Spider):

    handle_httpstatus_list = [301, 302]
    name = "stackoverflow"
    start_url = 'https://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean'

    def start_requests(self):
        yield scrapy.Request(self.start_url,meta={"lead_link":self.start_url},callback=self.parse)


    def parse(self,response):

        if response.meta.get("lead_link"):
            self.lead_link = response.meta.get("lead_link")
        elif response.meta.get("redirect_urls"):
            self.lead_link = response.meta.get("redirect_urls")[0]

        try:
            if response.status!=200 :raise
            if not response.css("[itemprop='text'] > h2"):raise
            answer_title = response.css("[itemprop='text'] > h2::text").get()
            print(answer_title)

        except Exception:
            print(self.lead_link)
            yield scrapy.Request(self.lead_link,meta={"lead_link":self.lead_link},dont_filter=True, callback=self.parse)


if __name__ == "__main__":
    c = CrawlerProcess({
        'USER_AGENT': 'Mozilla/5.0',
    })
    c.crawl(StackoverflowSpider)
    c.start()

问题:如何强制 scrapy 使用重定向的 url 进行回调

最佳答案

据我了解,您想要抓取链接,直到它停止重定向并最终获得 http 状态 200

如果是,那么您必须首先从代码中删除 handle_httpstatus_list = [301, 302] 然后在middlewares.py中创建一个CustomMiddleware

class CustomMiddleware(object):

    def process_response(self, request, response, spider):

        if not response.css("[itemprop='text'] > h2"):
            logging.info('Desired text not found so re-scraping' % (request.url))
            req = request.copy()
            request.dont_filter = True

            return req
        if response.status in [301, 302]:
            original_url = request.meta.get('redirect_urls', [response.url])[0]
            logging.info('%s is redirecting to %s, so re-scraping it' % (request._url, request.url))
            request._url = original_url
            request.dont_filter = True

            return request

        return response

那么你的蜘蛛应该看起来像这样

class StackoverflowSpider(scrapy.Spider):

    name = "stackoverflow"
    start_url = 'https://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean'

    custom_settings = {
        'DOWNLOADER_MIDDLEWARES': {
            'YOUR_PROJECT_NAME.middlewares.CustomMiddleware': 100,
        }
    }

    def start_requests(self):
        yield scrapy.Request(self.start_url,meta={"lead_link":self.start_url},callback=self.parse)

    def parse(self,response):

        answer_title = response.css("[itemprop='text'] > h2::text").get()
        print(answer_title)

如果您告诉我您正在抓取哪个网站,那么我可以为您提供帮助,您也可以向我发送电子邮件(在我的个人资料中)

关于python - 无法强制 scrapy 使用重定向的 url 进行回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59335468/

相关文章:

python - matplotlib 无法绘制单 channel 或灰度图像像素

html - 为什么 Chrome 不使用元刷新重定向

zend-framework - 重定向到 Zend 框架中的上一页

python - django 序列化外键对象

python - 在 Pandas 条形图上用值注释条形

python - 如何在Excel文件中导出wxpython gui文本?

python - 有效区分元组中不同可能的组合

python - 对二维 numpy 数组中的每个 NXN 子数组执行计算的最快方法

python-3.x - 使用 tkinter、MVC 和 Observables 设置 Entry 的值

.htaccess - 从非 www 重定向到 www 并强制使用 SSL