码迷,mamicode.com
首页 > 编程语言 > 详细

python 爬虫抓取今日头条街拍图片

时间:2017-10-07 14:27:11      阅读:326      评论:0      收藏:0      [点我收藏+]

标签:logs   print   conf   开发   port   arch   md5   github   turn   

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(rgallery: (.*?),\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 爬虫抓取今日头条街拍图片

标签:logs   print   conf   开发   port   arch   md5   github   turn   

原文地址:http://www.cnblogs.com/minorblog/p/7634454.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!