【Python3爬虫】今日头条街拍图片爬取
此次的目标是爬取今日头条街拍图片,并按一个图集一个文件夹保存下来,效果如下图:
一、页面分析
打开今日头条,输入街拍,选择图集,就可以看到各种街拍图片的图集:
根据以往的经验,这些图集信息应该是保存在Ajax中的,因此打开开发者工具,选择XHR,然后刷新页面,可以找到如下这个链接:
这个时候我们把页面往下滑动,可以看到又多了几条链接:
而这些链接的区别就是offset对应的数字不同,也就是说如果我们想得到多个链接们只需要改变offset对应的值就行了。
那我们要怎么得到图片的链接呢?点击开发者工具里的preview,把箭头一个个点开,然后在里面找到了图片链接:
这样我们就轻松得到了图片链接,然后就能进行爬取了。
二、目标实现
新建一个Scrapy项目,命名为TouTiao,打开items.py,代码如下
1 import scrapy
2
3
4 class ToutiaoItem(scrapy.Item):
5 image_urls = scrapy.Field() # 图集里的所有图片链接
6 image_name = scrapy.Field() # 图集名称
然后在spiders文件夹下新建一个TouTiao.py,代码如下:
1 import scrapy
2 import json
3 from TouTiao.items import ToutiaoItem
4 import time
5
6
7 class ToutiaoSpider(scrapy.Spider):
8 name = "TouTiao"
9 start_urls = [
10 'https://www.toutiao.com/search_content/?offset={}&format=json&keyword=%E8%A1%97%E6%8B%8D&autoload=true&'
11 'count=20&cur_tab=3&from=gallery'.format(i*20) for i in range(5)]
12
13 def parse(self, response):
14 time.sleep(2)
15 js = json.loads(response.body.decode('utf-8'))
16 data = js['data']
17 item = ToutiaoItem()
18 url_list = []
19 for d in data:
20 for i in d['image_list']:
21 url_list.append("http://" + i['url'])
22 # 每个图集下包含多张图片
23 item["image_urls"] = url_list
24 # 抓取图集标题
25 item['image_name'] = d['title']
26 yield item
打开pipelines.py,代码如下:
1 from scrapy.pipelines.images import ImagesPipeline
2 from scrapy import Request
3 import re
4
5
6 class TouTiaoPipeline(object):
7 def process_item(self,item,spider):
8 return item
9
10
11 class ImageSpiderPipeline(ImagesPipeline):
12 def get_media_requests(self, item, info):
13 # 循环每一张图片地址下载,若传过来的不是集合则无需循环直接yield
14 for image_url in item["image_urls"]:
15 # meta里面的数据是从spider获取,然后通过meta传递给下面方法:file_path
16 yield Request(image_url, meta={'name': item['image_name']})
17
18 # 重命名,若不重写这函数,图片名为哈希,就是一串乱七八糟的名字
19 def file_path(self, request, response=None, info=None):
20 # 提取url前面名称作为图片名。
21 image_guid = request.url.split('/')[-1]
22 # 接收上面meta传递过来的图集名称
23 name = request.meta['name']
24 # 删除图集名称中不符合文件夹名称规范的字符
25 name = re.sub(r'[?\\*|“<>:/]', '', name)
26 # 分文件夹存储的关键
27 filename = u'{0}/{1}.jpg'.format(name, image_guid)
28 return filename
打开settings.py,把ROBOTSTXT_OBEY设置为False,然后输入以下代码:
1 # 图片存储路径
2 IMAGES_STORE = 'E:\头条街拍图集'
3 DOWNLOAD_DALEY = 0.3
4
5 ITEM_PIPELINES = {
6 'TouTiao.pipelines.ImageSpiderPipeline': 300,
7 }
进行完如上步骤之后,运行我们的爬虫就行了。