运用python3 爬取盗版小说——一个最简单的爬虫

标签: python爬取小说  简单的爬虫

声明:本文只作为技术交流,看小说,请支持正版。

 

一次在网吧玩,看到旁边人在盗版网站上网络小说,多瞄了几眼,记下了网站,既然正好在学python,就拿它练练手。这样的小说网站没有APP,只能通过网页看,而且广告非常多,当然这就是他们的盈利手段。一般这样的盗版小说的结构非常简单,直接废话不多说,开始工作。


1.    获取一章的内容

这次是拿 笔趣阁http://www.biqukan.cc/ 这个网站开刀。

就以《神棍》——小楼独坐(书籍主页http://www.biqukan.cc/book/20461/ )作例子。不过还是那句话,请支持正版。


这个书籍的主页可以找到已经更新的任意一章,也就是说,这个页面其实包含了这本书每一章的URL。点开第一章,去到小说正文,查看网页源代码,由于这个网页做的非常简单,一看源代码能马上找到正文部分。






这样问题就变得简单了,也就是说我们只要拿到网站的源代码,就相当于拿到了正文。

获取网站的源代码有多个模块可以用,我比较常用的是requests 这个模块。(若之前没有安装这个模块的,可以通过在命令行输入命令 pip install requests 来安装,若不会安装 pip 的可以看我前面的文章,有安装的教程。)



import random
import requests

header = [{'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36'},{'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'},{'User-Agent':'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'},{'User-Agent':'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'},{'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'}]
# header 是用来伪装成浏览器发送请求,一般加上最好,header 信息可以通过浏览器查看,也可在网上搜索得到。
req = requests.get('http://www.biqukan.cc/book/20461/12592815.html',headers = header[random.randint(0,4)])   # 向目标网站发送 get 请求
result = req.content
result = result.decode('gbk')    #  查看网页源代码 看到 charset=gbk,即网页是用的 gbk 编码,故要用 gkb 的编码方式来解码,否则中文就会乱码。
print(result)





我们已经成功的拿到了网页源代码,但这里面只有标题和正文是我们能用上的,故我们要做进一步的处理,这里就需要用的正则表达式。而且这里面有个问题,原本一章的内容是分在了两个页面。比如第一章(1)的 URL 是 http://www.biqukan.cc/book/20461/12592815.html ,第一章(2) http://www.biqukan.cc/book/20461/12592815_2.html ,只有一个“_2”的区别,多试几章都是同样的规律,拿到一章完整的内容,需要拿到这两个页面的正文才完整。(严谨点的做法是通过正则去找URL,由于这个网站规律性很好,故简单通过在第一个url后面加”_2”的方法来处理。)
通过正则表达式来获取标题和正文,我们这里先获取第一章的完整内容。




import random
import requests
import re

header = [{'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36'},{'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'},{'User-Agent':'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'},{'User-Agent':'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'},{'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'}]

# header 是用来伪装成浏览器发送请求,一般加上最好,header 信息可以通过浏览器查看,也可在网上搜索得到。

req1 = requests.get('http://www.biqukan.cc/book/20461/12592815.html',headers = header[random.randint(0,4)])   # 向目标网站发送 get 请求
req2 = requests.get('http://www.biqukan.cc/book/20461/12592815_2.html',headers = header[random.randint(0,4)])
result1 = req1.content
result1 = result1.decode('gbk')    #  查看网页源代码 看到 charset=gbk,即网页是用的 gbk 编码,故要用 gkb 的编码方式来解码,否则中文就会乱码。
result2 = req2.content
result2 = result2.decode('gbk')
title_re = re.compile(r' <li class="active">(.*?)</li>') # 取出文章的标题
text_re = re.compile(r'<br><br>([\s\S]*?)</div>')  # 由于正文部分有很多的换行符,故要使用 [\s\S]
title = re.findall(title_re,result1)    # 找出标题
text1 = re.findall(text_re,result1)     # 找出第第一部分的正文
text2 = re.findall(text_re,result2)     # 找出第第二部分的正文
title = title[0]    # 由于返回的 title 是列表,故取出列表中的第一项
print(title)        # 打印出标题
text1.append(text2[0])      # 把正文两个部分添加到同一列表中,方便处理
text1 = '\r\n'.join(text1)  # 把两部分的正文连接成同一个个字符串
text1 = text1.split('\r\n') # 把字符串按照换行符分割
text_1 = []     # 添加一个空列表,用来装处理后的正文
for sentence in text1:
    sentence = sentence.strip()     # 去掉每一句两边的空格
    if ' ' in sentence:
        sentence = sentence.replace(' ','')    # 去掉句子中的  
        if '<br />' in sentence:
            sentence = sentence.replace('<br />','')    # 去掉句子中的 <br />
            text_1.append(sentence)
        else:
            text_1.append(sentence)
    elif '<br />' in sentence:
        sentence = sentence.replace('<br />','')
        text_1.append(sentence)
    elif '-->><p class="text-danger text-center mg0">本章未完,点击下一页继续阅读</p>' in sentence:
        sentence = sentence.replace(r'-->><p class="text-danger text-center mg0">本章未完,点击下一页继续阅读</p>', '')   # 去掉 -->><p class="text-danger text-center mg0">本章未完,点击下一页继续阅读</p>
        text_1.append(sentence)
    else:
        text_1.append(sentence)
count = text_1.count('')        # 统计列表中的空字符串
for i in range(count):
    text_1.remove('')           # 移除所有的空字符串
for sentence in text_1:
print(sentence)             # 打印出所有的正文


我们已经成功的获取到了第一章的所有内容,同时也将文章中不需要的符号,空格,广告都去掉了,剩下的工作就是获取到每一章的内容,把获取的内容写入本地的txt文件中,然后就可以在其他设备软件是看小说了。还记得前面说过,每一章的URL都在小说主页上有吗,那现在就需要在这里下手了。同时我们将刚才获取正文的这段代码写成一个函数,这样方便后面循环调用。要想把获取的内容写入本地 txt 文件中只要稍加修改代码就行了。


# 定义一个获取所有章节 URL 的函数
def get_url(url):
    req = requests.get(url,headers = header[random.randint(0,4)])
    result = req.content
    result = result.decode('gbk')
    res = r'<dd class="col-md-3"><a href=(.*?) title='  # 制定获取 url 的匹配规则,不知道是不是为了反爬,包裹url 的部分用的是单引号,部分用的双引号。故在匹配的时候,没有写入,到后面再处理这个问题。
    list_url = re.findall(res,result)
    list_url_ = []  # 定义一个空列表,来装处理后的各个章节的 url
    for url_ in list_url:
        if '"' in url_:         # 用 if 语句分别来处理单引号和双引号的问题,然后组装成完整的 URL
            url_ = url_.replace('"','')
            url_ = url_.replace('"', '')
            list_url_.append('http://www.biqukan.cc/book/20461/' + url_)
        elif "'" in url_:
            url_ = url_.replace("'", '')
            url_ = url_.replace("'", '')
            list_url_.append('http://www.biqukan.cc/book/20461/' + url_)
    return list_url_





最后写一个循环,就可以把所有的章节全部下载下来,可以在函数内部加一个 print ,方便实时观测进度。

for url_txt in get_url('http://www.biqukan.cc/book/20461/'):
    get_txt(url_txt)






至此,这本小说就已经爬取下来了,当然这个程序写的很简陋,代码好像写的也有点乱,但是在关键的地方后面都写有注释。今天就到这里,后面再慢慢完善代码。

欢迎交流。

版权声明:本文为weixin_40962422原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_40962422/article/details/78729132