导图社区 python爬虫基础(抓取小说实战说明)
网络爬虫,是一门比较通用的基础技术,各个领域都会有所涉及,比如做视觉算法的,也需要用到网络爬虫,例如调用 API 接口清洗数据等,这本质也都是一个小的爬虫程序。
编辑于2021-01-13 16:40:47python爬虫基础(抓取小说实战说明)
爬虫简介
网络爬虫,也叫网络蜘蛛(Web Spider)。 它根据网页地址(URL)爬取网页内容, 而网页地址(URL)就是我们在浏览器中输入 的网站链接。
URL 专业一些的叫法是统一资源定位符 (Uniform Resource Locator),它的 一般格式如下(带方括号[]的为可选项):
例: protocol :// hostname[:port] / path / [;parameters][?query]#fragment
URL 的格式主要由前个三部分组成:
protocol:第一部分就是协议,例如百度使用的 就是https协议;
hostname[:port]:第二部分就是主机名(还有端 口号为可选参数),一般网站默认的端口号为80, 例如百度的主机名就是www.baidu.com,这个就 是服务器的地址;
path:第三部分就是主机资源的具体地址,如目录和 文件名等。
审查元素
在浏览器的地址栏输入 URL 地址,在网页处 右键单击,找到检查。(不同浏览器的叫法不 同,Chrome 浏览器叫做检查,Firefox 浏览 器叫做查看元素,但是功能都是相同的)
简单实例
网络爬虫的第一步就是根据 URL ,获取网页的 HTML 信息。在 Python3 中,可以使用 urllib.request 和 requests 进行网页爬取。
urllib 库是 Python 内置的,无需我们额外安装, 只要安装了 Python 就可以使用这个库。
requests 库是第三方库,需要我们自己安装。
requests 安装
在 cmd 中,使用如下指令安装 requests : pip install requests或者easy_install requests
requests 库的基础方法如下:

http://docs.python-requests.org/zh_CN/latest/user/quickstart.html
requests.get()方法
向服务器发起get请求
例: # -*- coding:UTF-8 -*- import requests if __name__ == '__main__': target = "http://www.baidu.com/" req = requests.get(url = target) req.encoding = 'utf-8' print(req.text)
抓取小说并自动下载
爬虫步骤
发起请求:我们需要先明确如何发起 HTTP 请求,获取到数据。
解析数据:获取到的数据乱七八糟的,我们需要提取出我们想要的数据。
保存数据:将我们想要的数据,保存下载。
使用到的第三方库
BeautifulSoup
pip install beautifulsoup4
easy_install beautifulsoup4
lxml
pip install lxml
tqdm
pip install tqdm
安装
确定抓取地址
URL:https://www.xsbiquge.com/15_15338/8549128.html
发起请求
参考“简单实例”进行第一步
import requests if __name__ == '__main__': tar = "https://www.xsbiquge.com/15_15338/8549128.html" req = requests.get(url=tar) req.encoding = 'utf-8' print(req.text)
解析数据
审查元素
鼠标右键——选择检查——如左图所示操作

发现如下元素: <div id="content" style="font-size: 10pt;">
除了 div 字样外,还有 id 。id 就是 div 标签的属性, content是属性值,一个属性对应一个属性值。
使用BeautiSoup提取
获取单章小说详情
import requests from bs4 import BeautifulSoup if __name__ == '__main__': target = 'https://www.xsbiquge.com/15_15338/8549128.html' req = requests.get(url = target) req.encoding = 'utf-8' html = req.text bs = BeautifulSoup(html, 'lxml') texts = bs.find('div', id='content') print(texts)
bf.find('div', id='content') 的意思就是, 找到 id 属性为 content 的 div 标签。
清洗数据
import requests from bs4 import BeautifulSoup if __name__ == '__main__': target = 'https://www.xsbiquge.com/15_15338/8549128.html' req = requests.get(url = target) req.encoding = 'utf-8' html = req.text bs = BeautifulSoup(html, 'lxml') texts = bs.find('div', id='content') print(texts.text.strip().split('\xa0'*4))
texts.text 是提取所有文字,然后再使用 strip 方法去掉回车,最后使用 split 方法 根据 \xa0 切分数据,因为每一段的开头, 都有四个空格。
获取章节链接
审查元素,确定章节 存放信息,可编写代码
import requests from bs4 import BeautifulSoup if __name__ == '__main__': target = 'https://www.xsbiquge.com/15_15338/' req = requests.get(url = target) req.encoding = 'utf-8' html = req.text bs = BeautifulSoup(html, 'lxml') chapters = bs.find('div', id='list') chapters = chapters.find_all('a') for chapter in chapters: print(chapter)
bf.find('div', id='list') 就是找到 id 属性为 list 的 div 标签,chapters.find_all('a') 就 是在找到的 div 标签里,再提取出所有 a 标签
进一步解析
import requests from bs4 import BeautifulSoup if __name__ == '__main__': server = 'https://www.xsbiquge.com' target = 'https://www.xsbiquge.com/15_15338/' req = requests.get(url = target) req.encoding = 'utf-8' html = req.text bs = BeautifulSoup(html, 'lxml') chapters = bs.find('div', id='list') chapters = chapters.find_all('a') for chapter in chapters: url = chapter.get('href') print(chapter.string) print(server + url)
可以看到,chapter.get('href') 方法 提取了 href 属性,并拼接出章节的 url,使用 chapter.string 方法提取了 章节名。
保存数据
获取整本小说并下载
import requests import time from tqdm import tqdm from bs4 import BeautifulSoup def get_content(target): req = requests.get(url = target) req.encoding = 'utf-8' html = req.text bf = BeautifulSoup(html, 'lxml') texts = bf.find('div', id='content') content = texts.text.strip().split('\xa0'*4) return content if __name__ == '__main__': server = 'https://www.xsbiquge.com' book_name = '诡秘之主.txt' target = 'https://www.xsbiquge.com/15_15338/' req = requests.get(url = target) req.encoding = 'utf-8' html = req.text chapter_bs = BeautifulSoup(html, 'lxml') chapters = chapter_bs.find('div', id='list') chapters = chapters.find_all('a') for chapter in tqdm(chapters): chapter_name = chapter.string url = server + chapter.get('href') content = get_content(url) with open(book_name, 'a', encoding='utf-8') as f: f.write(chapter_name) f.write('\n') f.write('\n'.join(content)) f.write('\n')
下载过程中,我们使用了 tqdm 显示下载进度,让下载更加“优雅”
小说内容保存到“诡秘之主.txt”中, 小说一共 1416 章,下载需要大约 20 分钟,每秒钟大约下载 1 个章节。
20 多分钟下载一本小说, 想提速,可以使用多进程,大幅提高下载速度。 如果使用分布式,甚至可以1秒钟内下载完毕。 但是,不建议这样做。 我们要做一个友好的爬虫,如果我们去提速, 那么我们访问的服务器也会面临更大的压力。