一、简介
网络爬虫,也叫网络蜘蛛(Web Spider)。它根据网页地址(URL)爬取网页内容,而网页地址(URL)就是我们在浏览器中输入的网站链接。比如:www.baidu.com,它就是一个URL,在讲解爬虫内容之前,我们需要先学习一项写爬虫的必备技能:审查网页(html)元素。
不过多介绍审查网页元素内容,只需打开网页,鼠标右键,点击审查或者按F12
二、背景
网络爬虫的第一步就是根据URL,获取网页的HTML信息。在Python3中,可以使用urllib.request和requests进行网页爬取。
- urllib库是python内置的,无需我们额外安装,只要安装了Python就可以使用这个库。
- requests库是第三方库,需要我们自己安装。
- pip install requests
- 解析html网页使用Beautiful Soup,解析HTML信息,提取我们感兴趣的内容。对于本小节的实战,我们感兴趣的内容就是文章的正文。提取的方法有很多,例如使用正则表达式、Xpath、Beautiful Soup等。对于初学者而言,最容易理解,并且使用简单的方法就是使用Beautiful Soup提取感兴趣内容。
- pip install beautifulsoup4
requests库的开发者为我们提供了详细的中文教程,查询起来很方便。本文不会对其所有内容进行讲解,摘取其部分使用到的内容,进行实战说明。
三、实战
本文举例,仅供测试使用,并没有商业用途,地址:地址
完整代码如下:
# model
# param
# auth:lizhi.guo
# time:2022/5/16 16:37
import requests
from bs4 import BeautifulSoup
class spliderBQKarticleYNYH(object):
def __init__(self):
self.server = 'https://www.bqkan8.com'
self.target = 'https://www.bqkan8.com/1_1094/'
self.pathPre="D:\\openCVImage\\splider\\"
self.suff = ".txt"
self.names=[]
self.urls=[]
def getDownLoadUrls(self):
req = requests.get(self.target)
req.encoding = 'gbk'
html = req.text
bf = BeautifulSoup(html)
#通过审查元素,我们发现可以发现,这些章节目录都存放在了class属性为listmain的div标签下,选取部分html代码如下
div = bf.find_all('div', class_='listmain')
a_bf = BeautifulSoup(str(div[0]))
#我们看到每个章节的名字存放在了<a>标签里面。<a>标签还有一个href属性。这里就不得不提一下<a> 标签的定义了,
# <a> 标签定义了一个超链接,用于从一张页面链接到另一张页面。<a> 标签最重要的属性是 href 属性,它指示链接的目标。
#<a> 标签中href属性存放的属性值/1_1094/5403177.html是章节URLhttp://www.biqukan.com/1_1094/5403177.html的后半部分。
# 其他章节也是如此!那这样,我们就可以根据<a> 标签的href属性值获得每个章节的链接和名称了。
#总结一下:小说每章的链接放在了class属性为listmain的<div>标签下的<a>标签中。链接具体位置放在html->body->div->dl->dd->a的href属性中。
# 先匹配class属性为listmain的<div>标签,再匹配<a>标签
a = a_bf.find_all('a')
#因为find_all返回的是一个列表,里边存放了很多的<a>标签,所以使用for循环遍历每个<a>标签并打印出来,按需打印,排除其它a标签
for aobj in a[13:1332]:
sContext = aobj.string
self.names.append(sContext)
ahref = self.server + aobj.get('href')
self.urls.append(ahref)
def getBQKarticleYNYHContent(self,url):
req = requests.get(url=url)
req.encoding = 'gbk'
html = req.text
bf = BeautifulSoup(html)
#创建一个Beautiful Soup对象。BeautifulSoup函数里的参数就是我们已经获得的html信息。然后我们使用find_all方法,
# 获得html信息中所有class属性为showtxt的div标签。find_all方法的第一个参数是获取的标签名,第二个参数class_是标签的属性
texts = bf.find_all('div', class_='showtxt')
#find_all匹配的返回的结果是一个列表。提取匹配结果后,使用text属性,提取文本内容,滤除br标签。随后使用replace方法,
# 剔除空格,替换为回车进行分段。 在html中是用来表示空格的。replace('\xa0'*8,'\n\n')就是去掉下图的八个空格符号,并用回车代替:
content = texts[0].text.replace('\xa0' * 8, '\n\n')
orgHref = "(" + url + ")"
#踢除其它不需要的内容
content = content.replace(orgHref, "").replace("请记住本书首发域名:www.bqkan8.com。笔趣阁手机版阅读网址:m.bqkan8.com", "").replace(
"章节错误,点此举报(免注册)我们会尽快处理.举报后请耐心等待,并刷新页面。", "")
return content
#输出到文件,按照每个章节输出,有多少章节就输出多少个文件
def writeFile(self,name,content):
filePath = self.pathPre + name + self.suff
file = open(filePath, 'w', encoding='utf-8')
file.write(content)
if __name__ == "__main__":
dlclass= spliderBQKarticleYNYH();
dlclass.getDownLoadUrls()
for i in range(len(dlclass.names)):
sContext = dlclass.getBQKarticleYNYHContent(dlclass.urls[i])
dlclass.writeFile(dlclass.names[i],sContext)
四、实战截图
1、
五、问题记录
UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position ... 问题解决办法之一
在windows下面,新文件的默认编码是gbk,这样的话,python解释器会用gbk编码去解析我们的网络数据流txt,然而txt此时已经是decode过的unicode编码,这样的话就会导致解析不了,出现上述问题。 解决的办法就是,改变目标文件的编码:
file = open(filePath, 'w', encoding='utf-8')
声明:本文采用的素材,均是实验所用,均仅用于学习交流,没有任何商业用途。
欢迎进群学习交流:856044792