python 爬虫抓取今日头条街拍图片
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 爬虫抓取今日头条街拍图片相关的知识,希望对你有一定的参考价值。
1. 打开google浏览器,输入www.toutiao.com, 搜索街拍。
2.打开开发者选项,network监看加载的xhr, 数据是ajax异步加载的,可以看到preview里面的data数据
3.下拉刷新查看加载的offset,每次加载20条数据,data是json数据,里面的article_url,是图集详情页的url。
4.首先抓取索引页的内容
data数据来自于索引页的请求都里面的query str
1 # 提取索引页的数据 2 def get_page_index(offset, keyword): 3 data = { 4 ‘offset‘: offset, 5 ‘format‘: ‘json‘, 6 ‘keyword‘: keyword, 7 ‘autoload‘: ‘true‘, 8 ‘count‘: 20, 9 ‘cur_tab‘: 1 10 } 11 # 向路由中出入参数, 构建完整url 12 url = ‘http://www.toutiao.com/search_content/?‘ + urlencode(data) 13 try: 14 response = requests.get(url) 15 if response.status_code == 200: 16 return response.text 17 return None 18 except RequestException: 19 print(‘请求索引页出错‘) 20 return None
5. 接下来是解析索引页的数据,提取出所需要的详情页的url,索引页的data是json数据,里面的article_url,是图集详情页的url。
1 # 解析索引页的json数据(Preview),并提取详情页url 2 def parse_page_index(html): 3 try: 4 data = json.loads(html) 5 if data and ‘data‘ in data.keys(): 6 for item in data.get(‘data‘): 7 # 用生成器的方式,惰性获取详情页的url 8 yield item.get(‘article_url‘) 9 except JSONDecodeError: 10 pass
6. 有了详情页的url,接下来就是获取详情页的数据和代码了
1 # 获取详情页面的数据代码 2 def get_page_detail(url): 3 try: 4 response = requests.get(url, timeout=5) 5 if response.status_code == 200: 6 return response.text 7 return None 8 except RequestException: 9 print(‘请求详情页出错‘, url) 10 return None
7. 接着就是解析详情页面,并提取title, 和图片url, 详情页代码数据在Doc中查看, 注意提取的是组图,非组图被过滤了.url_list 是指三个地址都是图片的地址,我们只要有一个原始的url就可以了。
以某个详情页为例,在浏览器中输入http://www.toutiao.com/a6473742013958193678/。开发者选项,network, Doc
1 # 解析详情页面并提取title, 和图片url 2 def parse_page_detail(html, url): 3 soup = BeautifulSoup(html, ‘lxml‘) 4 title = soup.select(‘title‘)[0].get_text() 5 print(title) 6 images_pattern = re.compile(r‘gallery: (.*?),\\n‘) 7 result = re.search(images_pattern, html) 8 if result: 9 # 将json数据转换为python的字典对象 10 data = json.loads(result.group(1)) 11 if data and ‘sub_images‘ in data.keys(): 12 sub_images = data.get(‘sub_images‘) 13 images = [item.get(‘url‘) for item in sub_images] 14 for image in images: download_image(image)
# 返回标题,此详情页的url,和图片url列表 15 return { 16 ‘title‘: title, 17 ‘url‘: url, 18 ‘images‘: images 19 }
8. 把解析提取的数据存储到mongodb中,以字典的方式.
先写个mongo的配置文件config.py
1 MONGO_URL = ‘localhost‘ 2 MONGO_DB = ‘toutiao‘ 3 MONGO_TABLE = ‘toutiao‘ 4 5 GROUP_START = 0 6 GROUP_END = 20 7 8 KEYWORD = ‘街拍‘
然后连接本地mongo,存储数据
1 client = pymongo.MongoClient(MONGO_URL, connect=False) # connect=False防止多线程在后台多次连接mongo数据库 2 db = client[MONGO_DB] 3 4 # 把详情页面的url和标题(title)以及组图的地址list保存到mongo中 5 def save_to_mongo(result): 6 if db[MONGO_TABLE].insert(result): 7 print(‘存储到MongoDB成功‘, result) 8 return True 9 return False
9. 下载图片
1 # 下载图数据,并保存图片 2 def download_image(url): 3 print(‘正在下载‘, url) 4 try: 5 response = requests.get(url) 6 if response.status_code == 200: 7 # response.content 为二进制数据 8 save_image(response.content) 9 return None 10 except RequestException: 11 print(‘请求图片失败‘, url) 12 return None 13 14 15 # 保存图片 16 def save_image(content): 17 # 使用md5生成加密名字,同时防止相同的图片重复下载 18 file_path = ‘{0}/{1}.{2}‘.format(os.getcwd(), md5(content).hexdigest(), ‘jpg‘) 19 if not os.path.exists(file_path): 20 with open(file_path, ‘wb‘) as f: 21 f.write(content)
10. 爬虫主函数
1 def main(offset): 2 html = get_page_index(offset, KEYWORD) 3 for url in parse_page_index(html): 4 html = get_page_detail(url) 5 if html: 6 result = parse_page_detail(html, url) 7 if result: save_to_mongo(result)
11. 开启多进程
1 if __name__ == ‘__main__‘: 2 groups = [x * 20 for x in range(GROUP_START, GROUP_END)] 3 pool = Pool() 4 pool.map(main, groups)
12. 需要的库函数
1 import requests 2 import re 3 import pymongo 4 from urllib.parse import urlencode 5 from requests.exceptions import RequestException 6 from json.decoder import JSONDecodeError 7 from bs4 import BeautifulSoup 8 import json 9 import os 10 from hashlib import md5 11 from config import * 12 from multiprocessing import Pool
完整代码: https://github.com/huazhicai/Spider/tree/master/jiepai
以上是关于python 爬虫抓取今日头条街拍图片的主要内容,如果未能解决你的问题,请参考以下文章