版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/coloson/article/details/89151008
Python笔记(五) --写一个爬虫对新笔趣阁的小说进行爬取
作为一名资深书虫以及穷币大学生,一直在免费小说网站上看小说,与此同时也对那写垃圾弹窗广告深恶痛绝。如此一来,寻思着能不能写个爬虫把小说爬下来并保存到本地。
要爬取小说,先做好准备工作—收集每个章节的url
首先,我要爬取的小说是新笔趣阁的三寸人间,当它的域名也不只这一个,域名不同把源码改一下就行(http://www.xbiquge.la/10/10489/)。
先写一个访问页面的函数
import urllib.request
headers = { #构造请求头
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0'
}
def Get_Html(url):
Html = urllib.request.Request(url,headers=headers)#带请求头访问url
Html = urllib.request.urlopen(Html).read().decode('utf-8')#读取小说目录页面的源码,转换成utf-8的编码格式
return Html #返回页面源码
然后,我们需要从页面源码中提取出每个章节名称以及url(这里用到了正侧表达式)
这里需要对页面源码进行审计,了解它的结构,利用正侧表达式通过re.findall()匹配出整个页面中所以符合表达式的内容
#利用正侧表达式在源码中找出所需的内容
def Get_URL(directory_source):
reg = r'<dd><a href=\'/10/10489/(.*?)\' >(.*?)</a></dd>'#(.*?)中就是我们想要的内容
reg = re.compile(reg)
result = re.findall(reg, directory_source)#调用正侧表达式对页面源码进行匹配查找
return result #返回匹配中的内容
因为我们匹配中的章节名称以及相应的url都存储在一个列表中,不方便我们利用,所以我们需要整理一下,将每个章节名称以及相应的url放到一个临时列表放进URL_List列表中
URL_List = []#创建章节的url列表
#将找到的章节名称和url保存到列表中
def Get_List(result,directory_url):
for URL in result:
list = [] # 创建一个列表,用于临时存放章节名称,以及url
list.append(URL[1]) # 将章节名称临时存放在list中
list.append(directory_url + str(URL[0])) # 在审查元素中发现href并不完整,补充完整好url后,也将url存放进临时列表中
URL_List.append(list) # 将列别list保存到URL_List列表中
收集好url后,就开始写爬取正文内容的函数
这里出现了一个问题,几经百度也找不到解决方法,希望有大佬能为我解惑。
re.findall()匹配中的内容以列表形式保存在content中,也是列表中唯一的元素,但是我通过print(content[0])却不能完整的输出这个元素
列如:
list = ['123456']
print(list[0])
正常情况下应该打印:
123456
现在却只打印后面的一小部分
6
虽然我最终没用找到解决方法,但还是有办法解决的,就是内容转换成字符串,然后用replase替换掉html标签记忆多余符号,从而提取出正文
def Get_Novel(chapter_url):
Html = Get_Html(chapter_url)#将正文url传给访问页面函数,获取正文页面源码
reg = r'<div id="content">([\s\S]*?)<p>.+?</p></div>' #考虑到正文存在大量的html标签所以用([\s\S]*?)进行匹配
reg = re.compile(reg)#增加匹配准度
content = re.findall(reg,Html)#获取匹配中的内容
content = str(content).replace(' ','').replace('<br />','\n').replace(r'\r','').replace('[\'','').replace('\']','')
return content
这里是完整的代码
# -*- coding: utf-8 -*-
import urllib.request
import re
URL_List = []#创建章节的url列表
#定义请求头信息
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0'
}
#返回页面源码
def Get_Html(url): #访问小说目录界面
Html = urllib.request.Request(url,headers=headers)
Html = urllib.request.urlopen(Html).read().decode('utf-8')#读取小说目录页面的源码,转换成utf-8的编码格式
return Html #返回页面源码
#利用正侧表达式在源码中找出所需的内容
def Get_URL(directory_source):
reg = r'<dd><a href=\'/10/10489/(.*?)\' >(.*?)</a></dd>'#(.*?)中就是我们想要的内容
reg = re.compile(reg)
result = re.findall(reg, directory_source)#调用正侧表达式对页面源码进行匹配查找
return result #返回页面源码中与正侧表达式匹配的内容
#将找到的章节名称和url保存到列表中
def Get_List(result,directory_url):
for URL in result:
list = [] # 创建一个列表,用于临时存放章节名称,以及url
list.append(URL[1]) # 将章节名称临时存放在list中
list.append(directory_url + str(URL[0])) # 在审查元素中发现href并不完整,补充完整好url后,也将url存放进临时列表中
URL_List.append(list) # 将列别list保存到URL_List列表中
#获取小说正文
def Get_Novel(chapter_url):
Html = Get_Html(chapter_url)
reg = r'<div id="content">([\s\S]*?)<p>.+?</p></div>' #?启用非贪婪模式
reg = re.compile(reg)
content = re.findall(reg,Html)
content = str(content).replace(' ','').replace('<br />','\n').replace(r'\r','').replace('[\'','').replace('\']','')
return content
def main():
directory_url = 'http://www.xbiquge.la/10/10489/'
directory_source = Get_Html(directory_url)
result = Get_URL(directory_source)
Get_List(result,directory_url)
for i in range(len(URL_List)):
chapter_title = URL_List[i][0]
chapter_url = URL_List[i][1]
chapter_content = Get_Novel(chapter_url)
with open('三寸人间.txt','a') as content:#这里可以跟人需要修改,也可以将每个章节的正文内容放进以对应章节名称命名的文件中
content.write(chapter_title+'\n\n'+chapter_content+'\n\n\n')
if __name__ == '__main__':
main()