最近《传闻中的陈芊芊》十分的火,我也上车了 哈哈哈哈,但是电视剧已经不能满足我对剧情的好奇,总希望在小说里面找不同。
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 />。
拿爬取的内容跟原网页对比发现:
为空白
\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('《传闻中的陈芊芊》下载完成')
转载:https://blog.csdn.net/weixin_43787365/article/details/106518251