requests+mongodb爬取今日头条,多进程

  1 import json
  2 import os
  3 from urllib.parse import urlencode
  4 import pymongo
  5 import requests
  6 from bs4 import BeautifulSoup
  7 from requests.exceptions import ConnectionError
  8 import re
  9 from multiprocessing import Pool
 10 from hashlib import md5
 11 from json.decoder import JSONDecodeError
 12 from config import *
 13 
 14 client = pymongo.MongoClient(MONGO_URL, connect=False)
 15 db = client[MONGO_DB]
 16 
 17 
 18 def get_page_index(offset, keyword):
 19     data = {
 20         'autoload': 'true',
 21         'count': 20,
 22         'cur_tab': 3,
 23         'format': 'json',
 24         'keyword': keyword,
 25         'offset': offset,
 26     }
 27     params = urlencode(data)
 28     base = 'http://www.toutiao.com/search_content/'
 29     url = base + '?' + params
 30     try:
 31         response = requests.get(url)
 32         if response.status_code == 200:
 33             return response.text
 34         return None
 35     except ConnectionError:
 36         print('Error occurred')
 37         return None
 38 
 39 
 40 def download_image(url):
 41     print('Downloading', url)
 42     try:
 43         response = requests.get(url)
 44         if response.status_code == 200:
 45             save_image(response.content)
 46         return None
 47     except ConnectionError:
 48         return None
 49 
 50 
 51 def save_image(content):
 52     file_path = '{0}/{1}.{2}'.format(os.getcwd(), md5(content).hexdigest(), 'jpg')
 53     print(file_path)
 54     if not os.path.exists(file_path):
 55         with open(file_path, 'wb') as f:
 56             f.write(content)
 57             f.close()
 58 
 59 
 60 def parse_page_index(text):
 61     try:
 62         data = json.loads(text)
 63         if data and 'data' in data.keys():
 64             for item in data.get('data'):
 65                 yield item.get('article_url')
 66     except JSONDecodeError:
 67         pass
 68 
 69 
 70 def get_page_detail(url):
 71     try:
 72         response = requests.get(url)
 73         if response.status_code == 200:
 74             return response.text
 75         return None
 76     except ConnectionError:
 77         print('Error occurred')
 78         return None
 79 
 80 
 81 def parse_page_detail(html, url):
 82     soup = BeautifulSoup(html, 'lxml')
 83     result = soup.select('title')
 84     title = result[0].get_text() if result else ''
 85     images_pattern = re.compile('gallery: JSON.parse\("(.*)"\)', re.S)
 86     result = re.search(images_pattern, html)
 87     if result:
 88         data = json.loads(result.group(1).replace('\\', ''))
 89         if data and 'sub_images' in data.keys():
 90             sub_images = data.get('sub_images')
 91             images = [item.get('url') for item in sub_images]
 92             for image in images: download_image(image)
 93             return {
 94                 'title': title,
 95                 'url': url,
 96                 'images': images
 97             }
 98 
 99 
100 def save_to_mongo(result):
101     if db[MONGO_TABLE].insert(result):
102         print('Successfully Saved to Mongo', result)
103         return True
104     return False
105 
106 
107 def main(offset):
108     text = get_page_index(offset, KEYWORD)
109     urls = parse_page_index(text)
110     for url in urls:
111         html = get_page_detail(url)
112         result = parse_page_detail(html, url)
113         if result: save_to_mongo(result)
114 
115 
116 if __name__ == '__main__':
117     pool = Pool()
118     groups = ([x * 20 for x in range(GROUP_START, GROUP_END + 1)])
119     pool.map(main, groups)
120     pool.close()
121     pool.join()

 

posted @ 2018-09-27 17:19  zhong_sp  阅读(341)  评论(0编辑  收藏  举报