爬取今日头条街拍美图
Posted jonas-von
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了爬取今日头条街拍美图相关的知识,希望对你有一定的参考价值。
爬取今日头条街拍美图
一、项目需求
1. 抓取今日头条街拍图片,并将每组图片储存到本地。
2. 图片格式存储为jpg
3. 每组图片用一个独立的文件夹储存
二、项目分析
目标URL为:https://www.toutiao.com/search/?keyword=街拍,如下截图:
这里可以发现,目标URL是由ajax加载,然后用javascript渲染出来的。请求的参数有offset、format、keyword、autoload、count、cur_tab 和 from ,除了offset参数以外,其余的都是固定的参数(可以自行推理,拖动鼠标滚轮让下走则会继续发送ajax请求,再打开新的请求发现参数offset的值为20,第三个请求的offset值为40,也就是说,每次请求20组数据,其余的参数均不变)。再通过Preview选项卡观察data字段,会发现我们需要的数据就在这里面,以其中的一个为例:
我们需要的图片url就在image_list中,而这组图片的标题则在title字段中:
三、项目源码
import requests from urllib.parse import urlencode import os from hashlib import md5 from multiprocessing.pool import Pool def get_page(offset): """加载一个ajax请求的结果""" params = { ‘offset‘:offset, ‘format‘:‘json‘, ‘keyword‘:‘街拍‘, ‘autoload‘:‘true‘, ‘count‘:‘20‘, ‘cur_tab‘:‘3‘, ‘from‘: ‘gallery‘ } url = ‘http://www.toutiao.com/search_content/?‘ + urlencode(params) try: response = requests.get(url) if response.status_code == 200: return response.json() except requests.ConnectionError: return None def get_images(json): """解析方法,提取每条数据的image_list字段中的图片链接,将图片链接和所属标题一同返回""" if json.get(‘data‘): for item in json.get(‘data‘): title = item.get(‘title‘) images = item.get(‘image_list‘) if images: for image in images: yield { ‘image‘:image.get(‘url‘), ‘title‘:title } def save_image(item): """保存图片方法,根据item中的title来创建文件夹,然后请求图片链接,获取图片的二进制数据,并写入文件。图片命名使用了md5""" if not os.path.exists(item.get(‘title‘)): os.mkdir(item.get(‘title‘)) try: local_image_url = item.get(‘image‘) new_image_url = local_image_url.replace(‘list‘,‘large‘) response = requests.get(‘http:‘ + new_image_url) if response.status_code == 200: file_path = ‘{0}/{1}.{2}‘.format(item.get(‘title‘),md5(response.content).hexdigest(),‘jpg‘) if not os.path.exists(file_path): with open(file_path,‘wb‘) as f: f.write(response.content) else: print(‘Already Download‘,file_path) except requests.ConnectionError: print(‘Failed to Save Image‘) def main(offset): """主函数""" json = get_page(offset) for item in get_images(json): print(item) save_image(item) GROUP_START = 1 GROUP_END = 5 if __name__ == ‘__main__‘: pool = Pool() groups = ([x * 20 for x in range(GROUP_START,GROUP_END + 1)]) pool.map(main,groups) pool.close() pool.join()
以上是关于爬取今日头条街拍美图的主要内容,如果未能解决你的问题,请参考以下文章