python 爬虫今日头条 多线程

如果你是看崔庆才的教学视频,那有什么问题可以进来看看。
几乎每一个代码都有注释,因为今日头条的加载有了变化,所以视频中的代码不能运行

# coding:utf-8
from bs4 import BeautifulSoup
import requests
import re
import json
from time import ctime
import threading
import pymongo

client=pymongo.MongoClient()#连接MongoDB
db=client.taotiao#创建一个数据库
jiehe=db.toutia#一个集合(放文件的集合)
#以上是创建一个今日头条的集合(在MongoDB里面)

def get_page_index(i):#这个函数用来返回页面的
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'}
    try:
        url='https://www.toutiao.com/search_content/?offset=%s'%i+'&format=json&keyword=%E8%A1%97%E6%8B%8D&autoload=true&count=20&cur_tab=3&from=gallery'
        #注意中间的那个i,这是用字符串的加法来构造一个合理的请求url
        html=requests.get(url,headers=headers,verify=False)#由于这个网页需要一个安全验证,我们使用verify参数绕过验证
        if html.status_code == 200:#判断请求是不是成功的,状态码200表示是一个成功的请求
            return html.text
        return None
    except Exception:
        print('请求索引页出错')
        return None
def get_one_page(url):#解析一个详情页,查找每个图集中图片的地址
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'}
    html = requests.get(url, headers=headers, verify=False)

    pattern = re.compile('gallery.*?parse\("(.*u88c5.*?)"\),.*?siblingList', re.S)#用正则匹配出我们需要的一系列字符串
    #需要注意的是:正则中括号是需要转义的,而双引号不需要转意
    get_data = re.search(pattern, html.text)
    json_chuan = get_data.group(1)#用group方法提取出来我们需要的一段字符串,这里需要注意一个事情,见图
    x = ''#申明一个字符串对象
    for i in json_chuan:#这一段代码通过字符串的加法去除了正则匹配过来的多余的‘\’
        if i != '\\':#这一行表示如果i不等于\,(\需要转意)
            x = x + i

    dict_json = json.loads(x)#上一步去除了反斜杠,就是一个json的字符串,通过json.loads方法将字符串转化为py的dict
    if dict_json and 'sub_images' in dict_json:#这一步验证了1️⃣dict_json是否存在,2️⃣sub_images是否是一个键
        get_sub_images = dict_json.get('sub_images')#提取这个键的值,这个值就是我们需要的url

    x = []
    for y in get_sub_images:#是一个列表
        if y and 'url_list' in y:
            get_url = y.get('url_list')[0].get('url')
            x.append(get_url)
    return x
def processing(a):
    jsondata = get_page_index(a)
    test = json.loads(jsondata)  # 这一步将json字符串解码成python的字典的形式
    data = test.get('data')  # 获取我们要的data,data是一个大的字典,里面包含了很多的键值对
    for i in data:  # 依次提取data中的字典并将article搞出来
        url_raw = i.get('article_url')#这里有一个巨坑,看了好长时间
        #article_url的链接与详情页的连接多了一个‘group/’少了一个‘a’
        pattern = re.compile('(http://toutiao.com/)group/(\d+?/)')
        try:#这里的捕捉异常就是为了捕捉有些url不符合详情页的url
            get_url_string = re.search(pattern, url_raw)
            url = get_url_string.group(1) + 'a' + get_url_string.group(2)#这一行代码就是为了除去那个巨坑的
            title = i.get('title')#我们把详情页的url和整个图集的标题都提取出来了
            x = [url, title]
        except Exception:
            pass
        try:
            group_urls = get_one_page(x[0])
            b = {x[1]: group_urls}
            group_list.append(b)
        except Exception:
            pass


if __name__=='__main__':
    group_list=[]#就是图集的链接和标题
    processing_list=[]
    print('整个程序开始的时间',ctime())
    for i in range(2,15,2):#这里我们开启了一个多线程,节省了一分半钟的时间
        a=i*10
        t=threading.Thread(target=processing,args=(a,))
        processing_list.append(t)
    for i in processing_list:
        i.start()
    for i in processing_list:
        i.join()
    try:
        jiehe.insert_many(group_list)
    except Exception:
        pass
    print('整个程序结束的时间',ctime())



你可能感兴趣的:(python 爬虫今日头条 多线程)