如何使用Scrapy下载需要cookie的图像

时间:2017-03-31 14:55:24

标签: python cookies request scrapy python-requests

我使用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。

但是如何通过我的饼干罐?否则,它将重定向到登录页面。

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

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

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

2 个答案:

答案 0 :(得分: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请求并保存了图像(这是保存在与你的项目相同的目录中)。

使用PIL

安装pip install Pillow

答案 1 :(得分:0)

将您的cookie保存到item,然后自定义您自己的管道进行提取

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)