1、小说网
这两天学习 Python 基础,今天又学了一点爬虫,现在写一个小 demo 练练手。想要下载小说首先需要一个能在线观看的小说网站。我这里使用笔趣看小说网站,然后搜索斗破苍穹。
2、爬取章节目录
我们第一步要做的就是爬取斗破苍穹每个章节的 url 。这里我使用 requests 库进行爬取,requests 库是第三方库需要下载,具体下载方法这里不多解释,不是本博客的重点。
执行以下代码进行爬取。
# 爬取斗破苍穹的章节目录
import requests
# 斗破苍穹章节目录的 URL
url = 'https://www.biqukan.com/3_3037/'
req = requests.get(url=url)
print(req.text)
我们发现运行结果并不是我们要想要的,出现了乱码。
由上图我们可以看出网页使用的编码是 GBK 而我们的编译器是 UTF-8,我们需要进行转码。
# 爬取斗破苍穹的章节
import requests
url = 'https://www.biqukan.com/3_3037/'
req = requests.get(url=url)
req.encoding = 'GBK'
print(req.text)
这样就可以获得到我们想要的网页源码了,但是该网页源码包含太多其他标签。并不是只有我们想要的章节名称和章节的 url,我们还需要对网页源码进行解析,解析的方法如图:
解析的方法有很多,这里我使用 BeautifulSoup,经过观察我们发现章节目录是在 <div class="listmain"> 标签中所以我们需要截取。
执行以下代码,我们就可以得到 <div class="listmain"> 中的所有 a 标签。
# 爬取斗破苍穹的章节
import requests
from bs4 import BeautifulSoup
url = 'https://www.biqukan.com/3_3037/'
req = requests.get(url=url)
req.encoding = 'GBK'
div_bf = BeautifulSoup(req.text)
# 截取网页的div
div = div_bf.find_all('div', class_='listmain')
# 将截取到的div转成字符串在此进行解析
a_bf = BeautifulSoup(str(div[0]))
# 提取a标签元素
a = a_bf.find_all('a')
print(a)
我们要需要对 a 标签进行处理。
# 爬取斗破苍穹的章节
import requests
from bs4 import BeautifulSoup
url = 'https://www.biqukan.com/3_3037/'
req = requests.get(url=url)
req.encoding = 'GBK'
div_bf = BeautifulSoup(req.text)
# 解析目录的div
div = div_bf.find_all('div', class_='listmain')
# 将截取到的div转成字符串在此进行解析
a_bf = BeautifulSoup(str(div[0]))
# 提取a标签元素
a = a_bf.find_all('a')
# 域名
server = 'http://www.biqukan.com/'
for each in a:
print(each.string, server+each.get('href'))
a 标签的 href 属性存储的 url 是相对路径,所以我们还需要加上域名,可以发现我们得到的 a 标签并不是从第一章开始,a = a_bf.find_all('a')得到的 a 是一个列表我们可以舍去一些无用元素。
将 for 循环改成这样,我们就可以只拿到我们想要的 a 链接了
for each in a[12:-7]:
print(each.string, server+each.get('href'))
3、爬取章节内容
我们已经如愿以偿的到章节目录,接下来就是对章节内容的读取。
# 爬取斗破苍穹的章节内容
import requests
# 把url缓存第一章节的URL
url = 'https://www.biqukan.com//3_3037/1349252.html'
req = requests.get(url=url)
req.encoding = 'GBK'
print(req.text)
运行代码后,我们也读取到了章节内容的源码,不要高兴的太早,仔细的小伙伴会发现我们读取的源码并不完成。这是因为小说的内容并没放在 html 源码里面而是通过 js 渲染生成的,直接使用 requests.get()是读取不到的。
解决js渲染的方法如图:
解决 js 渲染的方法有很多,我这里使用 selenium/webdriver,selenium/webdriver 解析需要下载驱动,我下载的是 chromedriver。chromedriver下载地址
记得 chromedriver 和 Chrome 的版本需要对应,chromedriver 和 Chrome 的版本需要对应,chromedriver 和 Chrome 的版本需要对应。重要的事情说三遍,如果版本不对应程序肯定报错。
查看自己电脑 Chrome 的版本,在 Chrome 浏览器的地址栏上搜索 Chrome://version/
# 爬取斗破苍穹的章节内容
from selenium import webdriver
# 里面填写自己chromedriver安装的路径
driver = webdriver.Chrome('F:/chromedriver.exe')
driver.get('https://www.biqukan.com//3_3037/1349252.html')
print(driver.page_source)
driver.close()
使用 webdriver.Chrome()会打开一个 Chrome 浏览器,不用管。代码执行到 driver.close()浏览器会自动关闭。这时候我们发现我们读取到了章节的内容,但是很乱我们需要对内容进行处理。
# 爬取斗破苍穹的章节内容
from selenium import webdriver
from bs4 import BeautifulSoup
# 里面填写自己chromedriver安装的路径
driver = webdriver.Chrome('F:/chromedriver.exe')
driver.get('https://www.biqukan.com//3_3037/1349252.html')
bf = BeautifulSoup(driver.page_source)
# 截取内容的div
texts = bf.find_all('div', class_='showtxt')
# 将内容进行格式化
print(texts[0].text.replace('\xa0' * 8, '\t').replace('\n' * 2, '\n'))
driver.close()
到这里我们已经读取到小说的内容了。
4、文章的下载
我们已经读取到了文章的内容,接下来就是将内容下载成文件。
# 爬取斗破苍穹的章节内容
from selenium import webdriver
from bs4 import BeautifulSoup
# 里面填写自己chromedriver安装的路径
driver = webdriver.Chrome('F:/chromedriver.exe')
driver.get('https://www.biqukan.com//3_3037/1349252.html')
bf = BeautifulSoup(driver.page_source)
# 截取内容的div
texts = bf.find_all('div', class_='showtxt')
# 将内容进行格式化
content = texts[0].text.replace('\xa0' * 8, '\t').replace('\n' * 2, '\n')
driver.close()
with open("F:\斗之力,三段.txt", 'w', encoding='utf-8') as f:
f.write(content)
代码执行完毕,我们打开 F 盘就会发现我们下载好的文件。
5、下载斗破苍穹
根据上面讲述的所有步骤我们可以开始下载斗破苍穹了。
# 下载斗破苍穹
import requests, sys
from bs4 import BeautifulSoup
from selenium import webdriver
# 该类用于从笔趣看下载小说
class novel():
# 创建类的实例对象会执行的方法,用于初始化数据
def __init__(self, domainName, catalog, start, end):
# 小说网域名
self.domainName = domainName
# 小说目录链接(斗破苍穹)
self.catalog = catalog
# 存放章节名
self.names = []
# 存放章节链接
self.urls = []
# 章节数
self.nums = 0
# a标签的开始
self.start = start
# a标签的结尾
self.end = end
# 读取章节
def chapter(self):
req = requests.get(url=self.catalog)
# 设置编码
req.encoding = 'GBK'
div_bf = BeautifulSoup(req.text)
# 解析目录的div
div = div_bf.find_all('div', class_='listmain')
# 将截取到的div转成字符串在此进行解析
a_bf = BeautifulSoup(str(div[0]))
# 提取a标签元素
a = a_bf.find_all('a')
self.nums = len(a[self.start: self.end])
for each in a[self.start: self.end]:
# 添加章节名
self.names.append(each.string)
# 添加章节链接
self.urls.append(self.domainName + each.get('href'))
# 读取章节内容
def content(self, url):
# 里面填写自己chromedriver安装的路径
driver = webdriver.Chrome('F:/chromedriver.exe')
driver.get(url)
bf = BeautifulSoup(driver.page_source)
# 截取内容的div
texts = bf.find_all('div', class_='showtxt')
# 将内容进行格式化
content = texts[0].text.replace('\xa0' * 8, '\t').replace('\n' * 2, '\n')
# 关闭chromedriver打开的浏览器
driver.close()
# 返回章节的内容
return content
# 将内容写入文件 name 章节标题 path路径 content内容
def writeFile(self, name, path, content):
with open(path, 'w', encoding='utf-8') as file:
file.write(name + '\n\n' + content)
# 程序的入口
if __name__ == "__main__":
# 小说网域名
domainName = 'http://www.biqukan.com/'
# 小说目录链接(斗破苍穹)
catalog = 'https://www.biqukan.com/3_3037/'
# a标签的开始 (斗破苍穹是[12:-7],每个小说不一样)
start = 12
# a标签的结尾
end = -7
novel = novel(domainName, catalog, start, end)
# 得到小说的章节
novel.chapter()
print('小说开始下载:')
for i in range(novel.nums):
novel.writeFile(novel.names[i], 'F:\斗破苍穹\\'+novel.names[i]+'.txt', novel.content(novel.urls[i]))
print('小说下载完成')
小说内容是 js 动态渲染,爬虫必须等网页加载完毕才能爬取,效率很低,可以使用不是 js 动态渲染的小说网进行爬取,结果如下:
下载完后,发现章节顺序是乱的。那是因为循环下载的时候没有给每章节编号,加上编号顺序就不乱了。
标题:使用Python的爬虫下载小说(斗破苍穹)
作者:Yi-Xing
地址:http://47.94.239.232:10014/articles/2019/10/05/1570247153965.html
博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!