美文网首页
Python系列爬虫之Scrapy实战 | 爬取知乎表情包

Python系列爬虫之Scrapy实战 | 爬取知乎表情包

作者: 扒皮狼 | 来源:发表于2021-04-05 00:27 被阅读0次
    image.png

    前言

    今天我们就用scrapy爬取知乎表情包。让我们愉快地开始吧~

    开发工具

    Python版本:3.6.4
    相关模块:

    scrapy模块

    请求模块;

    fake_useragent模块;

    以及一些python自带的模块。

    环境搭建

    安装Python并添加到环境变量,pip安装需要的相关模块即可。

    原理简介

    原理其实蛮简单的,因为之前就知道知乎有个api一直可以用:

    https://www.zhihu.com/node/QuestionAnswerListV2
    post请求这个链接,携带的数据格式如下:
    
    data = {
               'method': 'next',
               'params': '{"url_token":%s,"page_size":%s,"offset":%s}'
    }
    1. url_token:
    问题id,譬如问题“https://www.zhihu.com/question/302378021”的问题id为302378021
    2. page_size:
    每页回答的数量(知乎最大只能是10)
    3. offset:
    当前显示的回答的偏移量
    

    就可以获得该问题下的所有答案啦,然后用正则表达式提取每个回答下的所有图片链接就OK了。

    具体实现的时候用的scrapy,先新建一个scrapy项目:

    scrapy startproject zhihuEmoji
    

    然后在spiders文件夹下新建一个zhihuEmoji.py文件,实现我们的爬虫主程序:

    '''知乎表情包爬取'''
    class zhihuEmoji(scrapy.Spider):
        name = 'zhihuEmoji'
        allowed_domains = ['www.zhihu.com']
        question_id = '302378021'
        answer_url = 'https://www.zhihu.com/node/QuestionAnswerListV2'
        headers = {
                    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',
                    'Accept-Encoding': 'gzip, deflate'
                }
        ua = UserAgent()
        '''请求函数'''
        def start_requests(self):
            offset = -10
            size = 10
            while True:
                offset += size
                data = {
                            'method': 'next',
                            'params': '{"url_token":%s,"page_size":%s,"offset":%s}' % (self.question_id, size, offset)
                        }
                self.headers['user-agent'] = self.ua.random
                yield scrapy.FormRequest(url=self.answer_url, formdata=data, callback=self.parse, headers=self.headers)
        '''解析函数'''
        def parse(self, response):
            # 用来保存图片
            if not os.path.exists(self.question_id):
                os.mkdir(self.question_id)
            # 解析响应获得问题回答中的数据, 然后获取每个回答中的图片链接并下载
            item = ZhihuemojiItem()
            answers = eval(response.text)['msg']
            imgregular = re.compile('data-original="(.*?)"', re.S)
            answerregular = re.compile('data-entry-url="\\\\/question\\\\/{question_id}\\\\/answer\\\\/(.*?)"'.format(question_id=self.question_id), re.S)
            for answer in answers:
                item['answer_id'] = re.findall(answerregular, answer)[0]
                image_url = []
                for each in re.findall(imgregular, answer):
                    each = each.replace('\\', '')
                    if each.endswith('r.jpg'):
                        image_url.append(each)
                image_url = list(set(image_url))
                for each in image_url:
                    item['image_url'] = each
                    self.headers['user-agent'] = self.ua.random
                    self.download(requests.get(each, headers=self.headers, stream=True))
                    yield item
        '''下载图片'''
        def download(self, response):
            if response.status_code == 200:
                image = response.content
                filepath = os.path.join(self.question_id, str(len(os.listdir(self.question_id)))+'.jpg')
                with open(filepath, 'wb') as f:
                    f.write(image)
    

    其中ZhihuemojiItem()用于存储我们爬取的所有图片链接和对应的回答id,具体定义如下:

    class ZhihuemojiItem(scrapy.Item):
        image_url = scrapy.Field()
        answer_id = scrapy.Field()
    

    OK,大功告成,完整源代码详见个人简介相关文件

    相关文章

      网友评论

          本文标题:Python系列爬虫之Scrapy实战 | 爬取知乎表情包

          本文链接:https://www.haomeiwen.com/subject/jamrkltx.html