2021-5-28
网络爬虫实战小白2(下载小说)
昨天慌慌张张、毛毛草草、连抄带袭写完代码,一看能用就得意洋洋觉得自己可以了,事实很快给了我一巴掌——还差得远那!
今天继续昨天的工作(其实打算做壁纸的,但是太难了!)
重复一次昨天的工作,发现收获manman
先给出完整代码(原创作者:Jack Gui):
import requests
import time
from tqdm import tqdm
from bs4 import BeautifulSoup
def get_content(target):
req = requests.get(url = target)
req.encoding = 'gbk'
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.ibooktxt.com/'
book_name = '赘婿.txt'
target = 'https://www.ibooktxt.com/0_60/'
req = requests.get(url = target)
req.encoding = 'gbk'
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='gbk') as f:
f.write(chapter_name)
f.write('\n')
f.write('\n'.join(content))
f.write('\n')
还是熟悉的配方,先搜到目标小说(这个小说免费看,起点里小说可以试读,但是不能审查元素,所以无法获取相关信息),然后requests.get(url = target)
通过网页地址获取小说的全部内容,
import requests
if __name__ == '__main__':
target = 'https://www.ibooktxt.com/0_60/xxxxx.html'
req = requests.get(url = target)
req.encoding = 'gbk'
print(req.text)
req.encoding = 'gbk'
这句话的意思是编码类型为gbk,编码类型至少有三种,不同的小说网址不一样,(区分一下,A:源网页编码;B:程序直接使用的编码;C:统一转换字符的编码)如果我们用的B与网页的A不同,那么打印出来的中文就是乱码,英文不受影响。
那么小说的A在哪里找呢?一般在三个可能的位置:
1、http header的Content Type中:charset=‘utf-8’或者’gbk’
2、meta charset
3、网页头中Document定义
一般都是:charset='utf-8'
或者'gbk'
只要更改代码就可以改变B:
req.encoding = 'gbk'
req.encoding = 'utf-8'
获得内容之后就要提取我们想要的就可以了,使用BeautifulSoup
解析数据
import requests
from bs4 import BeautifulSoup
if __name__ == '__main__':
target = 'https://www.ibooktxt.com/0_60/xxxxx.html'
req = requests.get(url = target)
req.encoding = 'gbk'
html = req.text
bs = BeautifulSoup(html, 'lxml')
texts = bs.find('div', id='content')
print(texts)
texts = bs.find('div', id='content')
这句话是用find
匹配数据中我们想要的div
标签,id
是此标签的一个属性,content
是对应的属性值。
print(texts.text.strip().split('\xa0'*4))
这句话是打印出的内容删除空格,和一些不要的标签。
到此为止我的的小说已经完美获取了,但是这仅仅获取了一章,一部小说那麽多章,照这样来是要累死人?不不,只要我们获取小说的章节目录,然后用章节目录里的链接信息获取每一章的内容,就能实现一部万字小说一键下载了,这就省事多了。
import requests
from bs4 import BeautifulSoup
if __name__ == '__main__':
target = 'https://www.ibooktxt.com/0_60'
req = requests.get(url = target)
req.encoding = 'gbk'
html = req.text
bs = BeautifulSoup(html, 'lxml')
chapters = bs.find('div', id='list')
chapters = chapters.find_all('a')
for chapter in chapters:
print(chapter)
chapters = bs.find('div', id='list')
这里的属性值为啥变成list
了?因为小说章节目录就在这里藏着呀!
chapters = chapters.find_all('a')
这句话是遍历chapters
中所有标签名为a
的标签。
url = chapter.get('href')
print(chapter.string)
print(server + url)
将标签a
中属性为href
的属性值给url
, server = 'https://www.ibooktxt.com'
,那么server + url
就不用说了,搭积木嘛。
现在我们获取了章节链接server + url
、章节名称chapter.string
、章节内容texts
,只要将鸡蛋放在篮子里就好了。
with open(book_name, 'a', encoding='gbk') as f:
f.write(chapter_name)
f.write('\n')
f.write('\n'.join(content))
f.write('\n')
完整代码请往上翻。
最后感谢大佬提供的代码和细致的讲解,虽然我还有很多不懂~~~