2021-05-28

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了?因为小说章节目录就在这里藏着呀!2021-05-28

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')

完整代码请往上翻。
最后感谢大佬提供的代码和细致的讲解,虽然我还有很多不懂~~~

上一篇:Ubuntu系统(64位)下安装并配置Hadoop-2.2.0集群


下一篇:建造者模式