【问题标题】:how to use Scrapy to download image that needs cookie如何使用 Scrapy 下载需要 cookie 的图片
【发布时间】:2017-08-25 21:43:46
【问题描述】:

我正在使用 scrapy 抓取网站 这就是我登录后维护cookie jar的方式

def start_requests(self):
    return [scrapy.Request("https://www.address.com", meta = {'cookiejar' : 1}, callback = self.post_login)]


def post_login(self, response):
    print('Preparing login')
    return [FormRequest.from_response(response,   #"http://www.zhihu.com/login",
                            meta = {'cookiejar' : response.meta['cookiejar']}, 
                            headers = self.headers,
                            formdata = {
                                'username': 'user',
                                'password': 'pass123'
                            },
                            callback = self.after_login,
                        )]

然后,我需要的每个请求

yield scrapy.Request(curr, meta={'cookiejar':response.meta['cookiejar']}, callback=self.parse_detail)

一切顺利,直到我需要从网站上抓取图像。 我将需要使用 urllib.request.urlretrive()、scrapy 的 imagePipeline 或类似工具来打开 image_url。

但是我怎样才能用它传递我的 cookie 罐呢?否则会跳转到登录页面。

或者有没有办法通过scrapy请求直接下载图片?

感谢 eLRuLL 为我解决问题 但是python3中的代码需要稍微修改一下

从 io 导入 BytesIO 而不是从 StringIO 导入 StringIO 然后在下面的代码中使用 BytesIO。

【问题讨论】:

  • 为什么需要urllib 来发出图像请求?如果你做一个scrapy请求,它会自动加载cookies
  • 我要下载图片,有没有办法通过scrapy请求获取图片内容?
  • 这是你的问题吗?如何将scrapy响应解析为图像对象?
  • 是的,我没有找到直接解析图像对象的scrapy响应的方法,你知道怎么做吗?
  • 好的,那我来回答问题

标签: python cookies request scrapy python-requests


【解决方案1】:

response.body 包含您需要的信息,您可以稍后将其解析为它是什么。

我不完全确定这适用于每种图像文件类型,但您可以在response.headers['content-type'] 中获得更多信息,以便您了解它实际上是哪种文件类型并使用相应的 python 模块来处理该文件类型:

from PIL import Image
from StringIO import StringIO

...

    def parse_image(self, response):
        i = Image.open(StringIO(response.body))
        i.save("imagefile.png")
        ...

您提出了一个scrapy请求并保存了图像(这与您的项目保存在同一目录中)。

pip install Pillow安装PIL

【讨论】:

  • 感谢你的帮助,你拯救了我的一天,让我试试这个方法
  • 谢谢,效果很好,但就我而言,我需要使用 BytesIO。
  • 很好,可以帮上忙!
  • @yixianhe如果对你有帮助记得采纳哦!
  • @eL Rull 我试图接受它,但现在没有按钮,也许还没有投票?
【解决方案2】:

将您的 cookie 保存到项目,然后自定义您自己的管道以提取

class MyFilesPipeline(FilesPipeline):
    def get_media_requests(self, item, info):
        if 'file_urls' not in item:
            return
        adapter = ItemAdapter(item)
        for file_url in adapter['file_urls']:
            yield scrapy.Request(file_url,
                                 headers = item["headers"], 
                                 meta={
                                        'cookiejar': item['cookiejar'],
                                        })
    def file_path(self, request, response=None, info=None, *, item=None):
            return 'files/' + os.path.basename(urlparse(request.url).path)

【讨论】:

    猜你喜欢
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2012-10-23
    • 1970-01-01
    相关资源
    最近更新 更多