requests分析Ajax来爬取今日头条街拍美图

#参考代码:https://github.com/Germey/TouTiao

import requests
from bs4 import BeautifulSoup
from urllib.parse import urlencode#可以将字典构造为url
import re
import json
import pymongo
import os
from multiprocessing import Pool#多进程方法

MONGO_URL = 'localhost'
MONGO_DB = 'toutiao'
MONGO_TABLE = 'toutiao'
'''
#占时没用,可以通过设置参数,实现抓取不同的数据
GROUP_START = 1
GROUP_END = 20
KEYWORD='街拍'
'''

#连接mongo数据库
client = pymongo.MongoClient(MONGO_URL, connect=False)
db = client[MONGO_DB]

def get_index():#获取第一页中的内容(可以改变关键字,获取不同页面的数据)
    data={
        'offset':0,
        'format':'json',
        'keyword':'性感美女',
        'autoload' :'true',
        'count':20,
        'cur_tab':3,
    }
    params = urlencode(data)#通过urlencode将字典构造为url
    base='https://www.toutiao.com/search_content/?'
    url=base+params#构造成我们需要的完整连接
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; rv:57.0) Gecko/20100101 Firefox/57.0'}
    response=requests.get(url,headers=headers)
    return response.text

def get_all_tz(text):#将获取的页面信息(json格式)解析为字典,然后从字典中提取我们需要的数据
    data = json.loads(text)#将获取的页面信息(json格式)解析为字典
    if 'data' in data.keys():
        for item in data.get('data'):
            yield item.get('article_url')
    return None

def get__tz__detail(url):#获取组图中每张图片的连接,
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; rv:57.0) Gecko/20100101 Firefox/57.0'}
    response=requests.get(url,headers=headers)
    html=BeautifulSoup(response.text,'lxml')
    title=html.title.get_text()#组图的名字
    images_pattern = re.compile(r'gallery: JSON.parse\(\"(.*?)\"\).*?siblingList',re.S)
    all_info = re.search(images_pattern,response.text)
    info=all_info.group(1).replace(r'\"', '"').replace(r'\\', '')
    data=json.loads(info)
    if  'sub_images' in data.keys():
        sub_images = data.get('sub_images')
        images=[item.get('url') for item in sub_images ]
        #将组图的信息设置成一个字典,便于存储和读取
       return  {
            'title':title,
            'url':url,
            'images':dict(zip([i.split('/')[-1]  for i in images],[i for i in images]))#将所有图片连接存储为一个字典
        }

def save_to_mongo(data):#存储到mongodb数据库的方法
    if db[MONGO_TABLE].insert(data):
        print('Successfully Saved to Mongo', data)
        return True
    return False
def save_to_pc(urls,name):#存储到本地电脑的方法
    os.chdir('E:\\toutiao')
    os.mkdir(name)
    os.chdir('E:\\toutiao\\'+name)
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; rv:57.0) Gecko/20100101 Firefox/57.0'}
    for url in urls:
        response=requests.get(url,headers=headers)
        with open(url.split('/')[-1]+'.jpg','ab') as f:
            f.write(response.content)

def main():#存储到mongodb,成功
    text=get_index()
    urls=get_all_tz(text)
    for url in urls:
        result=get__tz__detail(url)
        save_to_mongo(result)

def save_main():#存储到本地电脑,成功
    text=get_index()
    urls=get_all_tz(text)
    for url in urls:
        result=get__tz__detail(url)
        name= result.get('title')
        if  'images' in result.keys():
            images_url = result.get('images')
            save_to_pc(list(images_url.values()),name)

#没有使用多进程的启动方法次数,只抓取了第一页20个组图的数据(太多会很慢)
if __name__=='__main__':
    main()#成功存储到mongodb
    save_main()#成功存储到本地电脑

#使用多进程方法起动
#此时可以抓取多个页面
#需要重新get_index()方法
def get_index(offset):#通过设置offset参数,实现抓取多个页面
    data={
        'offset':offset,
        'format':'json',
        'keyword':'性感美女',
        'autoload' :'true',
        'count':20,
        'cur_tab':3,
    }

pool = Pool()
groups = ([x * 20 for x in range()])
pool.map(main, groups)#这里的main()方法也需要重写,实现同时存储到mongodb数据库和本地
pool.close()
pool.join()


你可能感兴趣的:(requests爬虫学习笔记,MongoDB)