【问题标题】:How do I intercept a request after all redirects are resolved but before page download with urllib2?在解决所有重定向后但在使用 urllib2 下载页面之前如何拦截请求?
【发布时间】:2023-12-10 12:46:02
【问题描述】:

我正在抓取新闻文章并使用 urllib2。它会自动处理重定向,我可以使用 geturl() 从响应中获取解析的 url

但是如果解析的 url 在某个列表中,我想停止请求,以避免花费时间和带宽下载页面。

只要回答这些问题就足够了

urllib.opener.open() 是否会下载页面,或者当您调用response.read() 时是否会发生这种情况?

有没有一种方法可以询问urllib2 来解决重定向问题?

【问题讨论】:

    标签: python http redirect urllib2


    【解决方案1】:

    经过一些快速而肮脏的实验,我想我可以说我找到了您问题的部分答案。默认情况下,opener.open()urlopen() 的行为方式相同。即使您只能通过read() 函数读取输出,他们也会下载您重定向到的页面。

    但是,您可以使用自己的处理程序覆盖这些默认值,并传递给build_opener()。例如,要使对某些 URL 的重定向失败,您可以通过子类化 HTTPRedirectHandler 来执行类似的操作:

    class MyRedirectHandler(urllib2.HTTPRedirectHandler):
        def http_error_302(self, req, fp, code, msg, hdrs):
            if fp.geturl().startswith('http://www.facebook.com/'):
                # This will raise an exception similar to this:
                # urllib2.HTTPError: HTTP Error 302: FOUND
                return None
            else:
                # Let the default handling occur
                return super(MyRedirectHandler, self).http_error_302(req, fp, code, msg, hdrs)
    

    你会这样使用它:

    opener = urllib2.build_handler(MyRedirectHandler)
    try:
        fp = opener.open(url)
    except urllib2.HTTPError:
        content = None
        print 'This URL is not allowed or something'
    else:
        content = fp.read()
    

    当然,您必须在 try/except 块中包含调用块才能捕获该异常。我想可能有办法克服这个问题,让处理更好,但我不确定。

    无论如何,您可以查看文档here 了解更多详细信息。

    希望对你有帮助。

    编辑

    实际上,您可能想要覆盖 redirect_request,它还涵盖其他重定向代码(不仅是 302)。按照this的说法,应该是要走的路。

    【讨论】:

    • 如何确定给定请求是否是最终重定向?每次重定向都会调用redirect_request(可能不止一个,这在新闻网站上很常见)
    • 你不知道什么时候是最后一个,除非你读了最后一个。那是因为重定向是通过标头完成的,没有实际内容就无法下载(据我所知)。您可以做的一件事是在到达您期望的页面 URL 时停止重定向,前提是您希望在最后一个 URL 中看到特定模式(例如 /news/xxxx/xxxx,就是这样,停止重定向)。跨度>
    最近更新 更多