python爬取豆瓣电影排行榜(python爬取少年派2原著小说)
python爬取豆瓣电影排行榜(python爬取少年派2原著小说)def 下载并解析某章节(章节地址 章节名称): print(章节名称 ' 开始下载。。。') 章节源码 = 获取网页源码(章节地址) 章节源码解析器 = BeautifulSoup(章节源码 'lxml') 本章内容代码 = 章节源码解析器.find('div' id='htmlContent') 本章内容代码转文本 = str(本章内容代码) 本章内容代码转文本 = 本章内容代码转文本.replace("<br/><br/>" "\n") 章节源码解析器 = BeautifulSoup(本章内容代码转文本 'lxml') 本章内容代码 = 章节源码解析器.find('
上次爬取200多章节的《天才基本法》因为没有多线程耗时5分钟才能下载完,决定学习多线程的相关内容,终于成功了,再次下载10秒钟就OK。现在换一部小说《少年派2》,介绍下多线程下载。
首先还是写一个根据网址获取html源码的通用函数,下载目录和每个章节都要调用它。这个函数是通用的,直接复制就行,无需修改。
import requests
from bs4 import BeautifulSoup
import threading
def 获取网页源码(url):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML like Gecko) Chrome/72.0.3626.119 Safari/537.36"
}
try:
网址请求 = requests.get(url=url headers=headers)
网址请求.raise_for_status()
网址请求.encoding = 网址请求.apparent_encoding
return 网址请求.text # 返回网页源码
except:
print('网页地址访问失败')
return '获取失败'
下载目录,除了网址,其余和上次一样。
# 开始爬取目录
目录地址 = 'xxxx/book/shaonianpai2.html'
目录源码 = 获取网页源码(目录地址)
章节地址和名称列表 = []
源码解析器 = BeautifulSoup(目录源码 'lxml')
目录代码 = 源码解析器.select('div > ul> li') # 层级选择
for 章节 in 目录代码:
if 章节.text == '':
continue
章节地址 = 章节.find('a').attrs['href']
章节名称 = 章节.a.string
章节地址和名称列表.append([章节地址 章节名称])
print('章节列表下载成功!')
不一样的是,每个章节的下载都放到一个函数里,供后面的线程代码调用。由于每个线程结束的时间不同,下载好的章节内容不能用列表,改用字典存储。
def 下载并解析某章节(章节地址 章节名称):
print(章节名称 ' 开始下载。。。')
章节源码 = 获取网页源码(章节地址)
章节源码解析器 = BeautifulSoup(章节源码 'lxml')
本章内容代码 = 章节源码解析器.find('div' id='htmlContent')
本章内容代码转文本 = str(本章内容代码)
本章内容代码转文本 = 本章内容代码转文本.replace("<br/><br/>" "\n")
章节源码解析器 = BeautifulSoup(本章内容代码转文本 'lxml')
本章内容代码 = 章节源码解析器.find('div' id='htmlContent')
本章内容文本 = 本章内容代码.text
章节内容字典[章节名称] = 本章内容文本
多线程下载:把每个章节的下载放入线程列表,设置主线程等待它们结束
# 多线程下载章节内容
章节内容字典 = {}
线程列表 = []
for 章节 in 章节地址和名称列表:
章节地址 = 章节[0]
章节名称 = 章节[1]
子线程 = threading.Thread(target=下载并解析某章节 args=(章节地址 章节名称))
线程列表.append(子线程)
for 子线程 in 线程列表:
子线程.setDaemon(True) # 设置为守护线程,主线程可以等待
子线程.start()
for 子线程 in 线程列表:
子线程.join()
最后根据章节顺序合并成一个文本文件。
# 保存到文件
电子书文件 = open('少年派2.txt' 'a' encoding="utf-8")
for 章节 in 章节地址和名称列表:
章节地址 = 章节[0]
章节名称 = 章节[1]
电子书文件.write(章节名称 章节内容字典[章节名称] "\n\n")
电子书文件.close()
print('大功告成!')
不会下载的可以评论区留下邮箱,我把文件发给你。