python下载古诗文网史书和部分诗集

闲暇之余,利用网络请求库requests结合BeautifulSoup实现对古诗文网的史书和部分诗集的爬取,已封装为一个类。

实现功能:

1.可以对输入的史书名(如'史记'、'汉书'、'明史',)进行搜寻和下载。
2.可以对输入的诗集名(如'唐诗三百首'、'爱情'、'小学古诗')进行搜寻和下载。
3.下载成的文件夹名称以找到的实际名字为准(如是诗集,可能比输入的名字多),路径默认为当前脚本同级目录。

代码如下:

import os
import random
import requests
from bs4 import BeautifulSoup
import re
import time
from xpinyin import Pinyin


class GuShiWen(object):
    """
      古诗文网操作类
    """
    def __init__(self):
        """
        初始化
        """
        # 浏览器标识集
        user_agent = [
            "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) "
            "Version/5.1 Safari/534.50",
            "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) "
            "Version/5.1 Safari/534.50",
            "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
            "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; ."
            "NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko",
            "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
        ]
        # 随机获取一个浏览器
        rand_agent = random.choice(user_agent)
        # 拼装请求头
        self.header = {
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,images/webp,images/apng,*/*;q=0.8",
            "User-Agent": rand_agent,
        }

    def get_proxy_content(self):
        """
        获取代理ip
        :return:代理ip
        """
        with open('hosts.txt','r') as fp:
            content = fp.read().split('\n')
        return content

    def get_cate_div_list(self, url, cate_lable):
        """
        获取分类的列表
        :param url: 详情页url
        :return:分类的列表/None
        """
        try:
            response = requests.get(url, headers=self.header,)
        except:
            return None
        response.encoding='utf8'
        result = response.content
        su = BeautifulSoup(result, 'lxml')
        sonsdiv= su.find('div', class_="sons")
        # print(sonsdiv)
        catedivs = sonsdiv.find_all('div', class_=cate_lable)
        # print(catedivs)
        return catedivs

    def get_gushi(self, url):
        """
        获得古诗或者文章的详情页
        :param url: url
        :return: 古诗url返回的页面的BeautifulSoup对象格式/None
        """
        try:
            response = requests.get(url, headers=self.header)
        except:
            return None
        response.encoding = 'utf8'
        result = response.content
        su = BeautifulSoup(result, 'lxml')
        return su

    def get_gushi_url(self, name):
        """
        判断专题的页面是否存在
        :param url: url
        :return: 古诗专题url/False,名称/None
        """
        # print(name)
        name_len = len(name)

        # print(pinyin)
        if len(name) == 2:
            pinyin = Pinyin().get_pinyin(name).replace('-', '')
            url = 'https://so.gushiwen.org/gushi/%s.aspx' % pinyin
            response = requests.get(url, headers=self.header)
            # print(response.status_code)
            content = response.content.decode('utf8')
            # print(content)
            if '该网页不存在或存在错误' in content:
                print('没有找到‘%s’相关古诗文专题!' % name)
                return False
            else:
                # print(url)
                return url
        else:
            rand_name = []
            for i in range(name_len-1):
                for y in range(i+1, name_len):
                    rand_name.append(name[i] + name[y])
            # print(rand_name)
            for r_name in rand_name:
                pinyin = Pinyin().get_pinyin(r_name).replace('-', '')
                # print(pinyin)
                url = 'https://so.gushiwen.org/gushi/%s.aspx' % pinyin
                response = requests.get(url, headers=self.header)
                # print(response.status_code)
                content = response.content.decode('utf8')
                # print(content)
                if '该网页不存在或存在错误' in content:
                    if r_name == rand_name[-1]:
                        print('没有找到‘%s’相关古诗文专题!' % name)
                        return False
                    continue
                else:
                    # print(url)
                    su = BeautifulSoup(content, 'lxml')
                    title = su.find('div', class_='title').get_text().strip()
                    # print(title)
                    if name in title:
                        # print(name, url)
                        return url
                    else:
                        if r_name == rand_name[-1]:
                            print('没有找到‘%s’相关古诗文专题!' % name)
                            return False
                        continue

    def get_guji_url(self, dirname):
        """
        判断史籍存在与否并返回目录页url
        :param dirname: 史籍名
        :return: 古籍目录页面url/False
        """
        url = 'https://so.gushiwen.org/search.aspx?value=' + dirname
        try:
            response = requests.get(url, headers=self.header)
        except:
            return None
        response.encoding = 'utf8'
        result = response.content
        # print(result)
        su = BeautifulSoup(result, 'lxml')
        div = su.find('div', class_="sonspic")
        # print(div)
        if div is None:
            print('没有找到"%s"相关史籍!' % dirname)
            return False
        find_p = div.find('div',class_='cont').find('p')
        find_name = find_p.find('b').get_text()
        if find_name != dirname:
            print('没有找到"%s"相关史籍!' % dirname)
            return False
        url = find_p.find('a')['href']
        # print(url)
        # print(find_name)
        url = 'https://so.gushiwen.org/' + url
        # print(url)
        return url

    def download_poem(self):
        """
        下载专题诗集
        :return:无
        """
        name = input('请输入要下载的古诗集专题名:')
        # 查询并获取输入诗集名的目录页面url
        url= self.get_gushi_url(name)
        # print(url)
        # 如果找不到诗集,下载失败
        if not url:
            print('下载诗集《%s》失败!' % name)
            return False
        # 创建路径准备下载
        if not os.path.exists(name):
            os.mkdir(name)
        # 将目录页面分解为大章节块
        cate_div_list = self.get_cate_div_list(url, "typecont")
        # 按章节进行下载
        self.download_cate(cate_div_list, name)

    def download_guji(self):
        """
        下载史籍
        :return: 无
        """
        name = input('请输入要下载史籍名:')
        # 查询并获取输入史籍名的目录页面url
        url = self.get_guji_url(name)
        # print(url)
        # 如果找不到史籍,下载失败
        if not url:
            print('下载史籍《%s》失败!' % name)
            return False
        # 创建路径准备下载
        if not os.path.exists(name):
            os.mkdir(name)
        # 将目录页面分解为大章节块
        cate_div_list = self.get_cate_div_list(url, "bookcont")
        # 按大章节进行下载
        self.download_cate(cate_div_list,name)

    def download_detail(self, gushilist, dir_name, catename = None):
        """
        具体下载某篇文章或诗文
        :return: 无
        """
        s = 1
        for x in gushilist:
            tittle = x.get_text()
            try:
                tittle = re.findall('(.*?)\(.*?\)', tittle)[0]
            except:
                pass
            detailurl = 'https://so.gushiwen.org' + x.find('a')['href']
            gushi = self.get_gushi(detailurl)
            age_author = gushi.find('p', class_='source').get_text()
            content = gushi.find('div', class_='contson').get_text()
            allcontent = tittle + '\n--' + age_author + '\n' + content
            if not catename:
                f = open(os.path.join('./' + dir_name, tittle + '.txt'), 'wb')
            else:
                f = open(os.path.join('./' + dir_name, catename, tittle + '.txt'), 'wb')
            f.write(allcontent.encode('utf8'))
            if catename:
                print('《%s》之《%s》第%d篇《%s》下载成功!!!' % (dir_name, catename, s, tittle))
            else:
                print('《%s》第%d篇《%s》下载成功!!!' % (dir_name, s, tittle))
            s += 1
        if catename:
            print('"%s"之----"%s"下载完成!----------------' % (dir_name, catename))
        time.sleep(2)

    def download_cate(self, cate_div_list, dir_name):
        """
        下载详情章节下的内容
        :return: 无
        """
        # print(cate_div_list)
        if len(cate_div_list) == 1:
            gushilist = cate_div_list[0].find_all('span')
            self.download_detail(gushilist, dir_name)
        else:
            for i in range(len(cate_div_list)):
                catediv = cate_div_list[i]
                catename = catediv.find('div',class_="bookMl").get_text()
                if not os.path.exists(os.path.join(os.path.dirname(__file__),dir_name,catename)):
                    os.mkdir(os.path.join(os.path.dirname(__file__),dir_name,catename))
                gushilist = catediv.find_all('span')
                self.download_detail(gushilist, dir_name, catename)
        print('下载《%s》成功!' % dir_name)

    def download(self):
        """
        选择要下载的类型进行下载
        :return: 无
        """
        choice = input('请选择你要下载的类型(1.史书 2.诗集),输入对应数字:')
        if choice == '1':
            self.download_guji()
        if choice == '2':
            self.download_poem()


if __name__ == '__main__':
    # 实例化古诗文对象
    gushiwen = GuShiWen()

    # 调用下载方法
    gushiwen.download()

    # ***************测试*******************************
    # gushiwen.get_gushi_url('小学古诗')
    # gushiwen.get_guji_url('元史')

运行的效果如下:

运行效果.png

下载后的文件如下:

下载文件夹.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,042评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,996评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,674评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,340评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,404评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,749评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,902评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,662评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,110评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,577评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,258评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,848评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,726评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,952评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,271评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,452评论 2 348

推荐阅读更多精彩内容