【问题标题】:Scrapy Download Image 403 ErrorScrapy下载图像403错误
【发布时间】:2014-11-27 14:56:47
【问题描述】:

我正在尝试从这个网站下载图片:http://www.domu.com/chicago/neighborhoods/humboldt-park/1641-n-maplewood-ave-apt-1-chicago-il-60647

目标网站最近更改了使用唯一 URL 提供图像的方式。下载图像时出现 403 错误。下方链接。我可以在浏览器中加载每个图像一次。图像加载一次后,后续请求会产生 403 错误。当我将浏览器更改为私人模式时,我可以多次重新加载图像。这让我相信他们正在以某种方式跟踪 cookie。我试图在 scrapy 中禁用 cookie,但继续收到 403 错误。我还尝试启用 cookie,但一次处理一个请求。这也会产生 403 错误。目标站点正在为缓存使用清漆服务器。我认为 Varnish 包含一些防刮技术。

http://www.domu.com/sites/default/files/styles/gallery/public/filefield/field_img/20141117_133559.jpg?itok=pDSP-06i

关于如何下载图片有什么想法吗?

【问题讨论】:

    标签: python scrapy varnish


    【解决方案1】:

    这是一个使用 Selenium Webdriver 和命令 wget 的可能解决方案。

    通过 Webdriver 模拟浏览器导航并提取唯一 url 并通过 wget 命令下载。

    from selenium import webdriver
    import time
    import scrapy
    class domuSpider(CrawlSpider):
        name = "domu_spider"
        allowed_domains = ['domu.com']
        start_urls = ['http://www.domu.com/chicago/neighborhoods/humboldt-park/1641-n-maplewood-ave-apt-1-chicago-il-60647']
    
        def __init__(self):
            self.driver = webdriver.Firefox()
    
        def parse(self, response):
            self.driver.get(response.url)
    
            for element in self.driver.find_elements_by_css_selector("img"):
                print element.get_attribute('src')
                time.sleep(1)
                os.system('wget ' + element.get_attribute('src'))
            self.driver.quit()
    

    http://selenium-python.readthedocs.org的文档

    【讨论】:

    • 绝对是一个合理的解决方案。我希望避免使用 selenium 并弄清楚如何用 scrapy 解决。我尝试通过代理和用户代理轮换 IP。两者都不能解决问题
    • 我想知道我是否可以直接从scrapy的响应中写入文件。
    • 我明白你的意思,但是当我读到 403 问题时,第一个好主意是 Selenium。几周前我遇到了一个类似的问题,它使用了一个动态加载图像的 ajax 脚本。了解该网站上的图片的确切传递方式会很有趣
    • 我想我把问题缩小到需要在图片的下载中间件的 Header 中添加引用者。至少这就是我可以在浏览器中复制 403 错误的方式。在浏览器中,如果请求包含引用者,则不会出现 403 错误。如果没有推荐人,我会收到 403 错误。
    【解决方案2】:

    我能够通过将引用者添加到标题中来解决这个问题。

    我用这篇文章来帮助: How to add Headers to Scrapy CrawlSpider Requests?

    这是我的自定义图像管道:

    class MyImagesPipeline(ImagesPipeline):
        def get_media_requests(self, item, info):
            return [Request(x, headers={'referer': 'http://www.domu.com'}) for x in item.get(self.IMAGES_URLS_FIELD, [])]
    

    【讨论】:

      【解决方案3】:

      试试这个:

      导入这些:

      import scrapy
      import urllib.request
      

      你的函数看起来像:

      def parse(self,response):
         #extract your images url
         imageurl = response.xpath("//img/@src").get()
         imagename = imageurl.split("/")[-1].split(".")
         imagename = "addsomethingcustom"+imagename[0] + imagename[-1]
         req = urllib.request.Request(imageurl, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36'})
         resource = urllib.request.urlopen(req)
         output = open("foldername/"+imagename,"wb")
         output.write(resource.read())
         output.close()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-15
        • 1970-01-01
        • 2020-12-25
        • 2011-06-26
        • 1970-01-01
        相关资源
        最近更新 更多