第一次爬小说,乱码?没安装Beautiful Soup库?

最近《传闻中的陈芊芊》十分的火,我也上车了 哈哈哈哈,但是电视剧已经不能满足我对剧情的好奇,总希望在小说里面找不同。

import requests
target = 'https://www.biqiuge.com/book/52415/85860763.html'
req = requests.get(url=target)
print(req.text)

当我满心欢喜的点了F5,出现了……嗯,看不到。😭
在这里插入图片描述

出现中文乱码,怎么办👀?

1、首先为什么会出现乱码。乱码的问题,本质上来说就是编码和解码采用的编码方案不同。
打开原网页,找到网页编码。
在这里插入图片描述
通过查看源代码可以发现这个网址采用的编码是GBK

 <meta http-equiv="Content-Type" content="text/html; charset=gbk" />

补充内容:
Content-Type:在HTTP协议消息头中,使用Content-Type来表示请求和响应中的媒体类型信息。它用来告诉服务端如何处理请求的数据,以及告诉客户端(一般是浏览器)如何解析响应的数据。

Content-Type:type/subtype ;parameter

  • type:主类型,任意的字符串,如text,如果是*号代表所有;
  • subtype:子类型,任意的字符串,如html,如果是*号代表所有,用“/”与主类型隔开;
  • parameter:可选参数,如charset,boundary等。

2、此时,我们需要将编码改为GBK。

encode()方法:以 encoding 指定的编码格式编码字符串。
encode()方法语法:

  • str.encode(encoding=‘GBK’,errors=‘strict’)

参数

  • encoding – 要使用的编码,如"GBK"。
import requests
target = 'https://www.biqiuge.com/book/52415/85860763.html'
req = requests.get(url=target)
req.encoding='GBK'
print(req.text)

在这里插入图片描述
3、获取了HTML信息,现在我们就需要把正文提取出来,不然看着脑子疼。🤨
先找到我们要找到文本所在处。
在这里插入图片描述
不难发现,文章的所有内容都放在了一个名为div的“东西下面”,这个”东西”就是html标签。HTML标签是HTML语言中最基本的单位,HTML标签是HTML最重要的组成部分。

<div id="content", class="showtxt">

id和class就是div标签的属性,content和showtxt是属性值,一个属性对应一个属性值,是用来区分不同的div标签。
class属性为showtxt的div标签。我们可以以此下手!

安装Beautiful Soup4失败?

Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据,有了它我们可以很方便地提取出HTML或XML标签中的内容。
并用findall()函数匹配所有符合规律的内容,并以列表的形式返回结果

from bs4 import BeautifulSoup
import requests
target = 'https://www.biqiuge.com/book/52415/85860763.html'
req = requests.get(url=target)
req.encoding='GBK'
html=req.text
bf=BeautifulSoup(html)
texts=bf.find_all('div',class_='showtxt')
print(texts)

兴奋的按下F5,又……?突然想到我昨天安装的是Beautiful Soup,

在这里插入图片描述
如果不加上 4,会是老版本也就是 bs3,它是为了兼容性而存在,目前已不推荐

怎么安装第三方库?

  • 先找到安装python的文件夹,并且找到Scrips。
  • 点进去,然后shift+右键
  • 找到在此处“打开Powershell窗口”,点他。
    -输入——pip install beautifulsoup4

在这里插入图片描述
在这里插入图片描述

安装好bs4之后,果然行了,但是还是有多余,比如div标签名,br标签,以及各种空格。怎么去除这些东西呢?我们继续编写代码。

<br> 可插入一个简单的换行符。

<br> 标签是空标签(意味着它没有结束标签,因此这是错误的:<br></br>)。在 XHTML 中,把结束标签放在开始标签中,也就是 <br />。

在这里插入图片描述
拿爬取的内容跟原网页对比发现:
在这里插入图片描述

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;为空白

\xa0表示不间断空白符,爬虫中遇到它的概率不可谓不小,而经常和它一同出现的还有\u3000、\u2800、\t等Unicode字符串。

find_all匹配的返回的结果是一个列表。提取匹配结果后,使用text属性,提取文本内容,滤除br标签。随后使用replace方法,剔除空格,替换为回车进行分段。 在html中是用来表示空格的。

replace(‘\xa0’*8,’\n\n’)就是去掉下图的八个空格符号,并用回车代替。

from bs4 import BeautifulSoup
import requests

target = 'https://www.biqiuge.com/book/52415/85860763.html'
req = requests.get(url=target)
req.encoding='GBK'
html=req.text
bf=BeautifulSoup(html)
texts=bf.find_all('div',class_='showtxt')
print(texts[0].text.replace('\xa0'*8,'\n\n'))

在这里插入图片描述
这样我们一章就爬完了。
就先这样8,溜了,去吃午饭了。

尝试爬取整本书

上面我们已经学会爬取一个章节。那么怎么爬取整本小说呢?

在这里插入图片描述
这些章节都存放在了class属性为listmain的div标签下,选取部分html代码如下:

<div class="listmain">
	<dl>
		<dt>《传闻中的三公主》最新章节列表</dt>
		<dd><a href ="/book/52415/85774549.html">第一百七十五章 真是好不要脸</a></dd>
		<dd><a href ="/book/52415/85774550.html">第一百七十四章 天下无不散之筵席</a></dd>
		<dd><a href ="/book/52415/85774551.html">第一百七十三章 要点东西</a></dd>
		<dd><a href ="/book/52415/85774552.html">第一百七十二章 陈芊芊算漏的那个人</a></dd>
		<dd><a href ="/book/52415/85774553.html">第一百七十一章 你把韩烁送走了</a></dd>
		<dd><a href ="/book/52415/85774554.html">第一百七十章 你不喜欢我</a></dd>
		<dt>《传闻中的三公主》正文卷</dt>
		<dd><a href ="/book/52415/86867523.html">第一章 阴差阳错</a></dd>
		<dd><a href ="/book/52415/86755792.html">第二章 当街抢亲</a></dd>
		<dd><a href ="/book/52415/86755791.html">第三章 影帝的指点</a></dd>
		<dd><a href ="/book/52415/86755790.html">第四章 穿越成女配</a></dd>
		<dd><a href ="/book/52415/86755789.html">第五章 离韩烁那扫把星越远越好</a></dd>
		<dd><a href ="/book/52415/86755788.html">第六章 这是杀马儆我啊</a></dd>
		<dd><a href ="/book/52415/86755787.html">第七章 论如何穿回现代</a></dd>
		<dd><a href ="/book/52415/86755786.html">第八章 一切都要给洞房让路</a></dd>
		<dd><a href ="/book/52415/86755785.html">第九章 你家守宫砂是日抛的啊</a></dd>
		<dd><a href ="/book/52415/86755784.html">第十章 酒中下毒</a></dd>
		<dd><a href ="/book/52415/86755783.html">第十一章 韩烁入狱</a></dd>
		<dd><a href ="/book/52415/86755782.html">第十二章 我怀孕了!</a></dd>
		<dd><a href ="/book/52415/85774552.html">第一百七十二章 陈芊芊算漏的那个人</a></dd>

	</dl>
</div>
1<div></div>限定了<div>标签的开始和结束的位置,他们是成对出现的,有开始位置,就有结束位置。
2、在<div>标签包含<dl>标签,那这个<dl>标签就是<div>标签的子节点,<dl>标签又包含<dt>标签和<dd>标签,那么<dt>标签和<dd>标签就是<div>标签的孙节点。
3、我们看到每个章节的名字存放在了<a>标签里面。<a>标签还有一个href属性。这里就不得不提一下<a>标签的定义了,<a>标签定义了一个超链接,用于从一张页面链接到另一张页面。<a> 标签最重要的属性是 href 属性,它指示链接的目标。

根据我们昨天提取章节的方法,得:
在这里插入图片描述
在这里插入图片描述
我们可以根据标签的href属性值获得每个章节的链接和名称了。

from bs4 import BeautifulSoup
import requests
if __name__ == "__main__":
    server='https://www.biqiuge.com/'
    target = 'https://www.biqiuge.com/book/52415/'
    req = requests.get(url = target)
    req.encoding='GBK'
    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')#find_all返回的是一个列表,里边存放了很多的<a>标签
    for each in a:#用for循环遍历每个<a>标签并打印出来
        print(each.string,server+each.get('href'))

在这里插入图片描述
发现上面有6个下面也会重复。

from bs4 import BeautifulSoup
import requests, sys

class downloader(object):

    def __init__(self):
        self.server = 'https://www.biqiuge.com/'
        self.target = 'https://www.biqiuge.com/book/52415/'
        self.names = []            #存放章节名
        self.urls = []            #存放章节链接
        self.nums = 0            #章节数

 
    def get_download_url(self):
        req = requests.get(url = self.target)
        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[6:])  #剔除不必要的章节,并统计章节数
        for each in a[6:]:
            self.names.append(each.string)
            self.urls.append(self.server + each.get('href'))

    def get_contents(self, target):
        req = requests.get(url = target)
        req.encoding='GBK'
        html = req.text
        bf = BeautifulSoup(html)
        texts = bf.find_all('div', class_ = 'showtxt')
        texts = texts[0].text.replace('\xa0'*8,'\n\n')
        return texts

    def writer(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\n')

if __name__ == "__main__":
    dl = downloader()
    dl.get_download_url()
    print('《传闻中的陈芊芊》开始下载:')
    for i in range(dl.nums):
        dl.writer(dl.names[i], '传闻中的陈芊芊.txt', dl.get_contents(dl.urls[i]))
        sys.stdout.write("  已下载:%.3f%%" %  float(i/dl.nums) + '\r')
        sys.stdout.flush()
    print('《传闻中的陈芊芊》下载完成')


在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值