你看网络小说么?使用爬虫将你喜欢的小说从网页上爬取下来吧!
首先输入关键词“伏天氏”,然后Google一下吧,我们会得到下图所示的搜索结果
我们直接点击第二个来源——笔趣阁进行爬取吧,即我们将要爬取的网页的url为: https://www.biquge.com.cn/book/31326/,进入页面后,我们可以看到《伏天氏》的全部目录,如下图所示
我们尝试点击其中的几个章节,会发现加载出每一个章节的正文。所以我们可以初步得出一个爬取思路:我们可以得到目录中每一个章节的url,然后通过循环即可爬取每一个章节的正文。那么目录中的每一个章节对应的url如何获取呢?你可能会想到我们前面爬取豆瓣相关网页的方法,即通过一定的规律构造url的列表,下面我们来分析此方法是否行得通。
第一章的url为 https://www.biquge.com.cn/book/31326/318451.html
第二章的url为 https://www.biquge.com.cn/book/31326/318452.html
第三章url为 https://www.biquge.com.cn/book/31326/318453.html从这里看好像是很有规律的,那么我们选取第九章的url看看是否符合这个规律 https://www.biquge.com.cn/book/31326/327615.html,可以发现是不符规律的!一般而言,各种小说的章节的url往往只有连续的几个章节有一点点规律,然后在某一章规律就会发生突变。显然,前面的方法在此不再适用。
我们还有一种方法,那就是获取目录页的源代码并从中提取出各个章节的url。通过检查按钮我们可以看到下图所示的源代码
从而知道所有的章节信息均位于<div id="list">下的<dd>标签中。所以我们可以先使用XPath获取所有的<dd>节点,再使用循环分别提取每个<dd>节点中的章节的url。代码如下:
import requests
from lxml import etree
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
}
def get_url_list(url):
html = requests.get(url,headers=headers)
html.encoding = 'utf-8'
html = etree.HTML(html.text)
dd_lists = html.xpath('//div[@id="list"]/dl/dd')
for dd in dd_lists:
url = dd.xpath('./a/@href')
title = dd.xpath('./a/text()')
print(title,url)
if __name__ == "__main__":
url = 'https://www.biquge.com.cn/book/31326/'
get_url_list(url)
输出结果如下
可以看到我们得到的url并不完整,应该在前面加上 https://www.biquge.com.cn
在上面的代码中,我们为了讲解的方便,获取了标题和url并打印出来,下面去除不必要的代码使得获取章节url的函数简单明了。
import requests
from lxml import etree
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
}
def get_url_list(url):
html = requests.get(url,headers=headers)
html.encoding = 'utf-8'
html = etree.HTML(html.text)
dd_lists = html.xpath('//div[@id="list"]/dl/dd')
for dd in dd_lists:
url = 'https://www.biquge.com.cn' + dd.xpath('./a/@href')[0]
urls.append(url)
return urls
if __name__ == "__main__":
url = 'https://www.biquge.com.cn/book/31326/'
get_url_list(url)
获取所有章节的url之后,我们就可以通过循环提取每个章节的正文了,为了讲解的方便,我们先看看如何提取第一章的正文。
首先点击第一章,跳转到正文页面,点击“检查”按钮,我们可以看到章节题目所在的位置,如图
正文所在的位置如下图
代码如下
def get_content(url):
html = requests.get(url,headers=headers)
html.encoding = 'utf-8'
html = etree.HTML(html.text)
"首先获取章节名称"
title = html.xpath('//h1/text()')
"获取正文"
content = html.xpath('//div[@id="content"]/text()')
print(content)
输出结果
可以看到成功提取出了正文信息,但是结果并不美观,我们使用前面学过的re库对输出结果进行处理,改进代码如下
def get_content(url):
html = requests.get(url,headers=headers)
html.encoding = 'utf-8'
html = etree.HTML(html.text)
"首先获取章节名称"
title = html.xpath('//h1/text()')[0]
print(title+'\n')
"获取正文"
contents = html.xpath('//div[@id="content"]/text()')
for content in contents:
content = re.sub('\xa0\xa0\xa0\xa0','',content)
print(content)
输出结果为
到此,我们就已经完成了第一章的爬取,但是我们并不需要将爬取到的内容打印到屏幕,为了方便平时阅读,我们应该将其保存为txt格式,代码如下
def get_content(url):
'打开一个文件方便后面储存信息'
file = open('C:/Users/asus/Desktop/伏天氏.txt','a')
html = requests.get(url,headers=headers)
html.encoding = 'utf-8'
html = etree.HTML(html.text)
"首先获取章节名称"
title = html.xpath('//h1/text()')[0]
file.write(title+'\n\n')
print('正在爬取:'+title+'('+url+')')
"获取正文"
contents = html.xpath('//div[@id="content"]/text()')
for content in contents:
content = re.sub('\xa0\xa0\xa0\xa0','',content)
file.write(content)
现在整个爬虫所需的函数我们都已讲解完毕,接下来我们将这些函数整合到一起将整本小说爬取下来。
import requests
from lxml import etree
import re
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
}
def get_url_list(url):
html = requests.get(url,headers=headers)
html.encoding = 'utf-8'
html = etree.HTML(html.text)
dd_lists = html.xpath('//div[@id="list"]/dl/dd')
urls = []
for dd in dd_lists:
url = 'https://www.biquge.com.cn' + dd.xpath('./a/@href')[0]
urls.append(url)
return urls
def get_content(url):
'打开一个文件方便后面储存信息'
file = open('C:/Users/asus/Desktop/伏天氏.txt','a')
html = requests.get(url,headers=headers)
html.encoding = 'utf-8'
html = etree.HTML(html.text)
"首先获取章节名称"
title = html.xpath('//h1/text()')[0]
file.write(title+'\n\n')
print('正在爬取:'+title+'('+url+')')
"获取正文"
contents = html.xpath('//div[@id="content"]/text()')
for content in contents:
content = re.sub('\xa0\xa0\xa0\xa0','',content)
file.write(content)
file.write('\n\n')
file.close()
if __name__ == "__main__":
url = 'https://www.biquge.com.cn/book/31326/'
urls = get_url_list(url)
for url in urls:
get_content(url)
输出结果为
我们保存txt如下图
至此,静待程序运行,我们就能将喜欢的小说爬取下来了。
总结
XPath的语法规则相对简单,但是必须对各个节点之间的关系非常熟悉,否则很容易得到一些空列表而找不到错误原因。本篇只是以《伏天氏》的爬取为例,整个笔趣阁的小说只有传入相应的url均可以成功爬取!