知乎

下载 APP
爬虫系列第七篇 使用XPath爬取小说《伏天氏》

你看网络小说么?使用爬虫将你喜欢的小说从网页上爬取下来吧!

首先输入关键词“伏天氏”,然后Google一下吧,我们会得到下图所示的搜索结果

我们直接点击第二个来源——笔趣阁进行爬取吧,即我们将要爬取的网页的url为: biquge.com.cn/book/3132,进入页面后,我们可以看到《伏天氏》的全部目录,如下图所示

我们尝试点击其中的几个章节,会发现加载出每一个章节的正文。所以我们可以初步得出一个爬取思路:我们可以得到目录中每一个章节的url,然后通过循环即可爬取每一个章节的正文。那么目录中的每一个章节对应的url如何获取呢?你可能会想到我们前面爬取豆瓣相关网页的方法,即通过一定的规律构造url的列表,下面我们来分析此方法是否行得通。

第一章的url为 biquge.com.cn/book/3132

第二章的url为 biquge.com.cn/book/3132

第三章url为 biquge.com.cn/book/3132从这里看好像是很有规律的,那么我们选取第九章的url看看是否符合这个规律 biquge.com.cn/book/3132,可以发现是不符规律的!一般而言,各种小说的章节的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并不完整,应该在前面加上 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均可以成功爬取!

编辑于 2019-04-19 · 著作权归作者所有
赞同 5
评论

聚圣源徐志胜脱口秀新华字典起名用字大全男微信群起名字家庭百度识图在线使用韩三千苏迎夏全文免费阅读陶渊明是哪个朝代的轮胎销售公司起名歌词中有iloveyou起名字女孩姓秦吴伟定lt3c地图下载孙权劝学译文电视剧战火中的青春江夏文化大道新公司起名字三字大全超市 起名起名网免费名字测分商业贷款利率2013西式快餐连锁加盟十六画康熙字典起名用字五行属金的公司起名学校的楼起什么名字好孩子生辰起名美容美发店起名字好港台言情店起名免费取名大全书店起什么名字好啊2022年属龙人的全年运势退伍时间随意的反义词淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻让美丽中国“从细节出发”清明节放假3天调休1天男孩疑遭霸凌 家长讨说法被踢出群国产伟哥去年销售近13亿网友建议重庆地铁不准乘客携带菜筐雅江山火三名扑火人员牺牲系谣言代拍被何赛飞拿着魔杖追着打月嫂回应掌掴婴儿是在赶虫子山西高速一大巴发生事故 已致13死高中生被打伤下体休学 邯郸通报李梦为奥运任务婉拒WNBA邀请19岁小伙救下5人后溺亡 多方发声王树国3次鞠躬告别西交大师生单亲妈妈陷入热恋 14岁儿子报警315晚会后胖东来又人满为患了倪萍分享减重40斤方法王楚钦登顶三项第一今日春分两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?周杰伦一审败诉网易房客欠租失踪 房东直发愁男子持台球杆殴打2名女店员被抓男子被猫抓伤后确诊“猫抓病”“重生之我在北大当嫡校长”槽头肉企业被曝光前生意红火男孩8年未见母亲被告知被遗忘恒大被罚41.75亿到底怎么缴网友洛杉矶偶遇贾玲杨倩无缘巴黎奥运张立群任西安交通大学校长黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发妈妈回应孩子在校撞护栏坠楼考生莫言也上北大硕士复试名单了韩国首次吊销离岗医生执照奥巴马现身唐宁街 黑色着装引猜测沈阳一轿车冲入人行道致3死2伤阿根廷将发行1万与2万面值的纸币外国人感慨凌晨的中国很安全男子被流浪猫绊倒 投喂者赔24万手机成瘾是影响睡眠质量重要因素春分“立蛋”成功率更高?胖东来员工每周单休无小长假“开封王婆”爆火:促成四五十对专家建议不必谈骨泥色变浙江一高校内汽车冲撞行人 多人受伤许家印被限制高消费

聚圣源 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化