使用 Python Requests 爬取 笔趣看 小说网站
使用工具:
- Python 3.6 +
- Requests 2.20 +
需要爬取的小说主站地址:
页面分析
1. 分析列表页面布局
使用浏览器审查元素,查找章节列表所在位置的 dom、class、id 等属性,可以看到所有的章节列表都在一个 class 为 “listmain” 的 div 中包含着,由此可以得出结论,该 div 即是我们需要定位的章节列表所在位置。
2、分析章节名称、链接、第一章起始位置
根据列表布局,可以看到,每个章节的章节名称、链接,都在 a 标签中,而小说的第一章,是在第 16 个 a 标签中。分析章节链接、名称、第一章起始位置
3、分析章节内容页
进入第一章节,利用浏览器审查元素,可以看到文章的内容都在一个 id 为 content,class 为 showtxt 的 div 中,由此我们可以获取到章节内容
代码实例
创建下载类,声明存放章节名称、章节链接、章节数的数组
1 2 3 4 5 6 7 8 9 10
| class download(object): def __init__(self): self.server = 'https://www.biqukan.com' self.target = self.server + '/1_1094' self.names = [] self.urls = [] self.nums = 0
|
在下载类中新建获取章节列表的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| def get_download_url(self): req = requests.get(url=self.target, verify=False) html = req.text div_bf = BeautifulSoup(html) div = div_bf.find_all('div', class_='listmain') a_bf = BeautifulSoup(str(div[0])) a = a_bf.find_all('a') self.nums = len(a[15:]) for href in a[15:]: self.names.append(href.string) self.urls.append(self.server + href.get('href'))
|
获取章节内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| def get_content(self, target): req = requests.get(url=target, verify=False) html = req.text bf = BeautifulSoup(html) texts = bf.find_all('div', class_='showtxt') texts = texts[0].text.replace('\xa0' * 8, '') texts = texts.replace('\n\n','\n') return texts
|
将内容写入到 txt 文件中
1 2 3 4 5 6 7 8 9 10 11
| """ name:文章名称 path:文章保存路径 text:文章内容 """ def write(self, name, path, text): write_flag = True with open(path, 'a', encoding='utf-8') as f: f.write(name + '\n') f.writelines(text) f.write('\n')
|
开始下载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| if __name__ == '__main__':
""" 压制由于忽略 HTTPS,导致的运行时警告 from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) """ from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
dl = download() dl.get_download_url() print('开始下载') for i in range(dl.nums): dl.write(dl.names[i], '一念永恒.txt', dl.get_content(dl.urls[i])) sys.stdout.write('正在下载 %s,已下载:%.3f%% \r' % (dl.names[i], float(i / dl.nums))) sys.stdout.flush() print('下载完成')
|