爬虫:小说下载

1、网络爬虫,推荐一个解析HTML的Python库–Requests-HTML
这个库的用法,可以参考如下网址:
https://blog.csdn.net/anonymous_qsh/article/details/79372524

2、写这个文章的目的,只是为了记录自己学习python爬虫项目所用。如果要看小说,请支持正版
本人学习的地址来源于:
https://www.w3cschool.cn/python3/python3-enbl2pw9.html

3、本项目需要安装的python包 requests_html

import logging
import time
from requests_html import HTMLSession as hs

4、日志模块(可有可无的模块,只是将日志设置一些级别,用于分析)

LocalDay = time.strftime("%Y-%m-%d")
logFile = r'D:\SpyderNovels\{0}.log'.format(LocalDay)
logging.basicConfig(level=logging.DEBUG,
             format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
             datefmt='%a, %d %b %Y %H:%M:%S',
             filename=logFile,
             filemode='a+')
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)

5、下载一个章节的示例:
(1)headers模拟手机或者浏览器,以’https://www.biqukan.com/1_1094/5403177.html’为例。因为控件元素不同,所以需要获取的就得跟着改变

headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36 OPR/53.0.2907.99'
}
webaddr='https://www.biqukan.com/1_1094/5403177.html'
def novelDown(webaddr):
    session = hs()
    request_novel=session.get(webaddr,headers=headers)
    request_novel.html.encoding='GBK'
    title = list(request_novel.html.find('h1'))[0].text # 获取小说标题
    FileName = open('D://test.txt', 'a', encoding='gb18030', errors='ignore')
    content = list(request_novel.html.find('div#content.showtxt'))[0].text # 获取小说内容
    FileName.write(title)
    FileName.write('\n\n')
    FileName.write(content)
    FileName.write('\n\n')
    FileName.close()

如何获取控件元素,也就是request_novel.html.find(‘h1’),request_novel.html.find(‘div#content.showtxt’)这里面的关键词是如何找到的呢?请看下面的截图
获取控件元素
文本内容
可以看到的是,在进入了F12的模式后,在右侧是F12后的html源码,当你指定到相对的控件元素上时,左侧对应的位置上,就是相对的控件查找内容了。因为需要的是小说内容,所以需要的是text属性。

6、获取小说所有章节:
这里需要介绍下request-html获取元素的方法:
支持CSS选择器和XPATH两种语法来选取HTML元素。
1、CSS选择器语法,它需要使用HTML的find函数,该函数有5个参数,作用如下:
selector,要用的CSS选择器;
clean,布尔值,如果为真会忽略HTML中style和script标签造成的影响(原文是sanitize,大概这么理解);
containing,如果设置该属性,会返回包含该属性文本的标签;
first,布尔值,如果为真会返回第一个元素,否则会返回满足条件的元素列表;
_encoding,编码格式。

from requests_html import HTMLSession as hs
headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 '
                      '(KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36 OPR/53.0.2907.99'
        }
target = 'http://book.zongheng.com/showchapter/672340.html'
session = hs()
r = session.get(target, headers=headers)
print(r.html.find('div.volume')[0].absolute_links)#首页获取

2、XPATH语法,这需要另一个函数xpath的支持,它有4个参数如下:
selector,要用的XPATH选择器;
clean,布尔值,如果为真会忽略HTML中style和script标签造成的影响(原文是sanitize,大概这么理解);
first,布尔值,如果为真会返回第一个元素,否则会返回满足条件的元素列表;
_encoding,编码格式。
Xpath选择法

for i in r.html.xpath("//div[@class='container']/div/div[@class='volume-list']/div/ul[@class='chapter-list clearfix']/li/a"):
    print(i.text)
    print(i.absolute_links)

打印结果:

新书感言
{'http://book.zongheng.com/chapter/672340/36896886.html'}
上架感言
{'http://book.zongheng.com/chapter/672340/38705697.html'}
请假一天,顺便小聊几句。
{'http://book.zongheng.com/chapter/672340/44658570.html'}
...

程序示例:

from requests_html import HTMLSession as hs

def get_story(url):
    global f
    session=hs()
    r=session.get(url,headers=headers)
    r.html.encoding='GBK'
    title=list(r.html.find('title'))[0].text#获取小说标题
    nr=list(r.html.find('.nr_nr'))[0].text#获取小说内容
    nextpage=list(r.html.find('#pb_next'))[0].absolute_links#获取下一章节绝对链接
    nextpage=list(nextpage)[0]
    if(nr[0:10]=="_Middle();"):
        nr=nr[11:]
    if(nr[-14:]=='本章未完,点击下一页继续阅读'):
        nr=nr[:-15]
    print(title,r.url)
    f.write(title)
    f.write('\n\n')
    f.write(nr)
    f.write('\n\n')
    return nextpage

def search_story():
    global BOOKURL
    global BOOKNAME
    haveno=[]
    booklist=[]
    bookname=input("请输入要查找的小说名:\n")
    session=hs()
    payload={'searchtype':'articlename','searchkey':bookname.encode('GBK'),'t_btnsearch':''}
    r=session.get(url,headers=headers,params=payload)
    haveno=list(r.html.find('.havno'))#haveno有值,则查找结果如果为空
    booklist=list(r.html.find('.list-item'))#booklist有值,则有多本查找结果
    while(True):
        if(haveno!=[] and booklist==[]):
            print('Sorry~!暂时没有搜索到您需要的内容!请重新输入')
            search_story()
            break
        elif(haveno==[] and booklist!=[]):
            print("查找到{}本小说".format(len(booklist)))
            for book in booklist:
                print(book.text,book.absolute_links)
            search_story()
            break
        else:
            print("查找到结果,小说链接:",r.url)
            BOOKURL=r.url
            BOOKNAME=bookname
            break


global BOOKURL
global BOOKNAME
url='http://m.50zw.net/modules/article/waps.php'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36 OPR/53.0.2907.99'
}
def main(BOOKURL,BOOKNAME):
    if BOOKURL == '' and BOOKNAME == '':
        search_story()
    else:
        chapterurl=BOOKURL.replace("book","chapters")
        session=hs()
        r=session.get(chapterurl,headers=headers)
        ch1url=list(r.html.find('.even'))[0].absolute_links#获取第一章节绝对链接
        ch1url=list(ch1url)[0]
        global f
        f=open("D://novels//"+BOOKNAME+'.txt', 'a',encoding='gb18030',errors='ignore')
        print("开始下载\n")
        nextpage=get_story(ch1url)
        while(nextpage!=BOOKURL):
            nextpage=get_story(nextpage)
        f.close

if __name__ == "__main__":
    BOOKURL = 'https://m.50zw.net/book_33097/'
    BOOKNAME = '独闯天涯'
    main(BOOKURL,BOOKNAME)

猜你喜欢

转载自blog.csdn.net/huoyingchong64/article/details/88558314