此次的目标是爬取今日头条街拍图片,并按一个图集一个文件夹保存下来,效果如下图:

 

一、页面分析

打开今日头条,输入街拍,选择图集,就可以看到各种街拍图片的图集:

根据以往的经验,这些图集信息应该是保存在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 }

进行完如上步骤之后,运行我们的爬虫就行了。

 

版权声明:本文为TM0831原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/TM0831/p/9782660.html