古诗文多线程

import hashlib

import requests,re
from lxml import etree
import pymongo
from queue import Queue
import threading
‘’’
使用第一种方法的弊端:
#1、线程的数量不可控。
#2、线程的执行顺序不可控。
控制线程的方法是使用队列
#使用线程类创建
#第一步:改成线程类
‘’’
#创建一个类 负责线程要做的事情
class Gushiwen(threading.Thread):
def init(self,q_type=None,crawl=None):
#经过初始化,入队操作,多线程的第一步开始了
#实现 传入队列和入队的名字,以及请求头
super().init()
self.q_type = q_type
self.name = crawl
self.ajax_headers = {
‘user-agent’: ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36’,
‘cookie’: ‘login=flase; Hm_lvt_9007fab6814e892d3020a64454da5a55=1604653021,1604664055,1604711185; ASP.NET_SessionId=mi5gzudp2jtxammt0ke31pwd; wxopenid=defoaltid; Hm_lpvt_9007fab6814e892d3020a64454da5a55=1604711960’,

}
    pass
def get_xpath(slef,url):
    '''
    发送请求,获取古诗文首页html
    :param url:
    :return:
    '''
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36',
        'cookie': 'login=flase; login=flase; wxopenid=defoaltid; Hm_lvt_9007fab6814e892d3020a64454da5a55=1604653021,1604664055,1604711185,1605251746; Hm_lpvt_9007fab6814e892d3020a64454da5a55=1605251748',

    }
    response = requests.get(url,headers=headers)
    # print(response.text)
    return etree.HTML(response.text)

def get_note_trans(self,id):
    #(三) 获取诗文注释,
    """以五为纽扣总领各个方法,提取每条诗文的信息

    通过ajax获取注释和解析
    :param id:
    :return:
    """

    #https://so.gushiwen.cn/nocdn/ajaxfanyi.aspx?id=75B9117033181D93
    ajax_url = 'https://so.gushiwen.cn/nocdn/ajaxfanyi.aspx?id={}'.format(id)
    response = requests.get(ajax_url,headers=self.ajax_headers)
    tree_part = etree.HTML(response.text)
    #song_trans,song_note
    song_trans = tree_part.xpath('string(//div[@class="contyishang"]/p[1])')
    song_note = tree_part.xpath('string(//div[@class="contyishang"]/p[2])')
    # print(song_trans,song_note)
    return song_trans,song_note

def get_shanxi(self,id):
    #(四)获取赏析
    '''
    获取赏析
    :param id:
    :return:
    '''
    ajax_url = 'https://so.gushiwen.cn/nocdn/ajaxshangxi.aspx?id={}'.format(id)
    response = requests.get(ajax_url,headers=self.ajax_headers)
    tree_part = etree.HTML(response.text)
    shanxi = tree_part.xpath('string(//div[@class="contyishang"])')
    # print(shanxi)
    return shanxi


def write_to_mongo(self,item):
    #(六)   五的方法调用我 写入mongo文件写的是作者 注释 赏析整个字典
    '''
    将数据写入mongo
    :param item:
    :return:
    '''
    #1、创建一个连接
    client = pymongo.MongoClient()
    #2、连接一个数据库
    #client['数据库的名字']
    db = client['古诗文']
    #3、使用db数据库引用来操作集合:db['集合的名字']
    db['songs'].update({'song_id':item['song_id']},{'$set':item},True)
    print(item)


def get_md5(self,text):
    #对古诗文的url哈希加密,为了变成数字更方便比较写入的主键,提高写入效率
    return hashlib.md5(text.encode('utf-8')).hexdigest()


def parse_song(self,tree,url):
    #(五) 对诗文页面信息的提取 其中有展开更多,调用方法获取
    '''
    提取诗歌信息
    :param tree:
    :return:
    '''
    song_infso = tree.xpath('//div[@class="cont"]//p[@class="source"]/a/text()')
    # print(song_infso)
    #作者
    song_author = song_infso[1]
    #朝代
    song_dynasty = song_infso[0]
    #诗歌名称
    song_title = tree.xpath('//div[@class="cont"]//h1/text()')[0]
    # print(song_title,url)
    #诗歌内容--爬取新闻--string可以保持格式
    song_content = tree.xpath('string(//div[@class="cont"]//div[@class="contson"])')
    # print(song_content)

    #注释和解析
    zhushi_a_href = tree.xpath('//div[contains(@id,"fanyi")]/div/div[3]/a/@href')
    if zhushi_a_href:
        #有点击展开更多
        # print(zhushi_a_href)
        #提取id
        #javascript:fanyiShow(677,'75B9117033181D93')
        zhushi_id = re.search(r',\'(.*?)\'\)',zhushi_a_href[0]).group(1)
        # print(zhushi_id)
        song_trans,song_note = self.get_note_trans(zhushi_id)
    else:
        #没有点击展开更多
        # print(zhushi_a_href)
        #翻译
        song_trans = tree.xpath('string(//div[@class="contyishang"]/p[1])')
        #注释
        song_note = tree.xpath('string(//div[@class="contyishang"]/p[2])')

    #赏析
    shanxi_a_href = tree.xpath('//div[contains(@id,"shangxi")]/div/div[3]/a/@href')
    if shanxi_a_href:
        #有展开更多
        shanxi_id = re.search(r',\'(.*?)\'\)',shanxi_a_href[0]).group(1)
        # print(shanxi_id)
        shanxi = self.get_shanxi(shanxi_id)
        # print(1)
    else:
        #无展开更多
        # song_analyze = tree.xpath('string(//div[@class="contyishang"]/p[2])')
        print(song_title, url)
        shanxi = tree.xpath('//div[@class="contyishang"]/p[1]/text()')[-1]
        # print(shanxi)

    item = {}
    item['song_author'] = song_author
    item['song_dynasty'] = song_dynasty
    item['song_title'] = song_title
    item['song_content'] = song_content
    item['song_trans'] = song_trans
    item['song_note'] = song_note
    item['shanxi'] = shanxi
    item['song_id'] = self.get_md5(url)

    print(item)
    self.write_to_mongo(item)

(一)、

def get_song_types(self):

    # 1、获取分类列表
    base_url = 'https://so.gushiwen.cn/shiwen/'
    #获得诗文网页html
    tree_index = self.get_xpath(base_url)
    # 获取诗歌分类
    song_types = tree_index.xpath('//div[@class="cont"]/a/@href')
    return song_types

def parse_song_type(self,song_type):
    #(八) 传入的是诗文类别
    '''
    解析是个分类
    :param song_type:
    :return:
    '''
    # print(song_type)
    full_type_url = 'https://so.gushiwen.cn' + song_type
    tree_type = self.get_xpath(full_type_url)
    song_urls = tree_type.xpath('//div[@class="typecont"]/span/a/@href')
    # print(song_urls)
    # 3、进入诗歌详情页,获取诗歌信息
    for song_url in song_urls:
        if 'https:' not in song_url:
            full_song_url = 'https://so.gushiwen.cn' + song_url
        else:
            full_song_url = song_url
        tree_song = self.get_xpath(full_song_url)
        # 4、提取数据
        self.parse_song(tree_song, full_song_url)


# def main(self):
#     #1、获取分类列表
#     base_url ='https://so.gushiwen.cn/shiwen/'
#     tree_index = self.get_xpath(base_url)
#     #获取诗歌分类
#     song_types = tree_index.xpath('//div[@class="cont"]/a/@href')
#     #2、循环遍历诗歌分类,进入分类页面,获取该分类下的所有诗歌详情页url
#     for song_type in song_types:
#         # print(song_type)
#         full_type_url = 'https://so.gushiwen.cn' + song_type
#         tree_type = self.get_xpath(full_type_url)
#         song_urls = tree_type.xpath('//div[@class="typecont"]/span/a/@href')
#         # print(song_urls)
#         # 3、进入诗歌详情页,获取诗歌信息
#         for song_url in song_urls:
#             if 'https:' not in song_url:
#                 full_song_url = 'https://so.gushiwen.cn' + song_url
#             else:
#                 full_song_url = song_url
#             tree_song = self.get_xpath(full_song_url)
#             # 4、提取数据
#             self.parse_song(tree_song, full_song_url)

def run(self):
    #(七) 任务队列的执行调用
    while True:#一个线程重复不断做多个任务
        if self.q_type.empty():#任务队列为空,线程就停止工作
            break
        #线程正常工作的步骤
        #1、从任务队列获取一个任务
        #get出队  q_type=诗文的类
        song_type = self.q_type.get()
        print(f'@{self.name}开始爬取{song_type}')
        self.parse_song_type(song_type)

if name == ‘main’:
“”"“将诗文类型定位为循环条件,开启多线程,线程定为四个并取名”""
g = Gushiwen()
#开启多线程
#1、创建一个任务队列
#明确任务:任务就是顶层循环条件–诗歌类型
q_type = Queue()
# (二) 将诗文类别入队 2、初始化任务队列
song_types = g.get_song_types()
for song_type in song_types:
#put:队列的入队
q_type.put(song_type)
#3、创建一个list, # 这个list的长度就是线程的数量, list里面的内容就是线程的名字
crawl_list = [‘aa’,‘bb’,‘cc’,‘dd’]
#4、循环这个list,开启多线程
for crawl in crawl_list:
#创建线程
t = Gushiwen(q_type,crawl)
#启动线程
t.start()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值