python3正则+bs4+requests爬取今日头条街拍图片(ajax+html)
2018-03-26 18:34
639 查看
import json from _md5 import md5 from multiprocessing.pool import Pool import re import os import pymongo import requests from bs4 import BeautifulSoup from config import * # 链接mongodb数据库,多进程这里可能会报警告 client = pymongo.MongoClient(MONGO_URL,connect=False) # 定义一个数据库 db = client[MONGO_DB] def get_page_list(offset,keyword): ''' 获取主页面所有帖子的链接 ''' # 请求ajax的一些参数,通过浏览器F12看到的 params = { 'offset': offset, 'format': 'json', 'keyword': keyword, 'autoload': 'true', 'count': '20', 'cur_tab': 1, 'from': 'search_tab' } # from urllib.parse import urlencode # 用下面这种要import这个 # url解析自带的,就是把那个参数弄成一个链接,教程用的是下面这种方式把参数和url拼接 # url = 'https://www.toutiao.com/search_content/?' + urlencode(params) url = 'https://www.toutiao.com/search_content' try: # 我是把参数传入到get请求里面,如果用上面那种,这里的params形参就要删掉 response = requests.get(url,headers = HEADERS,params=params) # 因为要返回的是一个文本,所以用response.text,若要返回二进制数据,用response.content return response.text except: # 可能会url请求出错,避免停止,捕获一下异常 return None def parse_page_list(html): ''' 解析主页,取得帖子的链接 ''' # 把得到的ajax弄成一个json,方便处理,另外,注意是loads不是load data = json.loads(html) # 下面的内容是分析浏览器F12的network中的各种数据得到的 if data and 'data' in data.keys(): # 数据是层层字典嵌套的,一步步取出来 for item in data.get('data'): # 这个yield如果不懂可以理解为return的高级版本 yield item.get('article_url') def get_page_detail(url): ''' 根据主页的那些链接,访问帖子 ''' try: response = requests.get(url,headers=HEADERS) # 帖子请求成功才返回 if response.status_code == 200: return response.text return None except: return None def parse_page_detail(html): ''' 爬取帖子里面的所以照片链接和帖子名称 ''' try: # 一开始用的正则,有点小错误,直接拿汤器祭神 soup = BeautifulSoup(html, 'lxml') # 用选择,直接找到项目为title的内容 title = soup.select('title')[0].get_text() # 这是图片的正则模式 pattern = re.compile('"(http:.*?)"', re.S) # 找到所有的图片链接 images = re.findall(pattern,html) except: return None # 以特定格式返回,title是str,images是list return { 'title':title, 'images':images } def save_to_mongo(result): ''' 存储 { 'title':title, 'images':images } ''' # 把结果插入到表MONGO_TABLE中,成功返回True,失败False if db[MONGO_TABLE].insert(result): print('存到mongodb成功: ',result['title']) return True return False def download_save_image(url): ''' 下载图片,并保存到本地 ''' try: # 封装请求 response = requests.get(url,headers=HEADERS) # 如果是图片就返回content好,如果是网页就text content = response.content # 图片的存路径,因为图片可能会重复,所以加一个md5的命名规则,避免重复下载 file_path = '{0}/images/{1}.{2}'.format(os.getcwd(), md5(content).hexdigest(),'jpg') # 我是把图片都放在images文件夹下,如果还要分得更细,可以再创建一个"./images/图片集名字"这样的文件夹 dir = '{0}/images'.format(os.getcwd()) # 如果没有images文件夹,就新建一个 if not os.path.exists(dir): os.mkdir(dir) # 这个就是创建图片(因为用了md5,所以不允许有重复的图片) if not os.path.exists(file_path): with open(file_path,'wb') as f: f.write(content) print('图片保存成功:'+url) except: return None def main(offset): # 获取主页html html = get_page_list(offset,KEYWORD) # 解析上面的html得到链接 url_list = parse_page_list(html) for url in url_list: # 进入详情页 html = get_page_detail(url) if html: # 得到详情页的图片链接 result = parse_page_detail(html) # 如果图片链接结果不为空 if result and result['images']: # 先存相关信息到mongo save_to_mongo(result) # 再下载一份到本地 for url in result['images']: download_save_image(url) if __name__ == '__main__': # 三行加起来是并行进行 l = [i*20 for i in range(START_OFFSET,END_OFFSET)] pool = Pool() pool.map(main,l)
config.py
# 定义一些变量,等下直接导入就好了 # 下面分别是host,数据库名,表名 MONGO_URL = 'localhost' MONGO_DB = 'toutiao' MONGO_TABLE = 'toutiao' # 起始页面 START_OFFSET = 0 END_OFFSET = 10 # 搜索关键词 KEYWORD = '街拍' # 假装是浏览器的头 HEADERS = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36', 'x-requested-with':'XMLHttpRequest' }
窗口效果:
本地保存:
爬虫偶尔能成功,主要好像是因为加了并行,容易被反吧。
容易遇到:
<html><head></head><body></body></html> <html><head></head><body></body></html> <html><head></head><body></body></html> <html><head></head><body></body></html> <html><head></head><body></body></html> <html><head></head><body></body></html> <html><head></head><body></body></html>
若有改进方法,不吝赐教。
相关文章推荐
- Python基于分析Ajax请求实现抓取今日头条街拍图集功能示例
- Python爬虫-分析Ajax抓取今日头条街拍美图
- requests分析Ajax来爬取今日头条街拍美图
- python 抓取今日头条街拍图片并下载到本地
- Python爬虫实战02:分析Ajax请求并抓取今日头条街拍
- 使用python3分析Ajax爬取今日头条上的街拍美图
- 分析Ajax请求并爬取下载今日头条街拍美图
- python 抓取头条街拍图片
- Python爬虫之四:今日头条街拍美图
- python爬今日头条(ajax分析)
- 今日头条街拍图片爬取
- requests多进程爬取今日头条街拍--记录
- 爬取今日头条街拍美女图片
- 分析AJAX抓取今日头条街拍美图(下)
- 爬虫实践---今日头条<街拍>图片
- 分析AJAX抓取今日头条街拍美图(存储)
- 小白学python-今日头条街拍美图详解
- 分析Ajax抓取今日头条街拍美图
- 分析AJAX抓取今日头条街拍美图(上)
- python多线程爬取-今日头条的街拍数据(附源码加思路注释)