Python爬虫(四)-截取数据
库需求
from bs4 import BeautifulSoup
import re
项目代码示例
# 正则表达式匹配规则
findLink = re.compile(r'<a href="(.*)">')
findTitle = re.compile(r'rel="bookmark">(.*)</a>')
findExcerpt = re.compile(r'<div class="entry excerpt">.*<p>(.*)</p>', re.S) # re.S表示匹配时跳过换行符
findImage = re.compile(r'src="(.*)" srcset')
findPostView = re.compile(r'count">(\d*)</span>')
# 爬取网页
def getData(baseUrl):
# 1
dataList = []
page = 0
while(page>=0): # 搜索循环
page += 1
url = baseUrl + str(page) # 页面地址更新
# 2
html = askUrl(url) # 获取页面html文本
# 3
if html == "": # 404时,html为空,即已获取玩全部页面,结束循环
break
# 4
soup = BeautifulSoup(html, "html.parser") # 使用html解析来处理html变量(变量名)
for item in soup.find_all("article"): # 匹配article标签
data = []
item = str(item) # 转换为字符串格式
link = re.findall(findLink, item) # 链接获取
data.append(link[0])
title = re.findall(findTitle, item) # 标题获取
data.append(title[0])
excerpt = re.findall(findExcerpt, item) # 概述获取
excerpt = excerpt[0].replace('<br/>', ' ') # 去除概述中换行符
data.append(excerpt)
image = re.findall(findImage, item) # 图片地址获取
data.append(image[0])
# 5
getPostData(data, link[0]) # 阅读数量获取
dataList.append(data) # 将所有截取的数据添加进数据存储列表
# 6
for data in dataList: # 打印列表,查看是否正确
for item in data:
print(item)
print()
return dataList
def getPostData(dataList, url): # 获取文章内数据
html = askUrl(url)
soup = BeautifulSoup(html, "html.parser")
item = soup.find_all(class_="post-views-count") # 找到span标签,且class为post-views-count。
item = str(item)
postView = re.findall(findPostView, item) # 获取阅读数量
dataList.append(postView[0])
return dataList
正则表达式
这部分的正则表达式都挺简单的,只要通过查看网页源代码,找到数据附近的字符,按正则表达式规则定义就完成了。
但在匹配时,有出现需要匹配前一行或后一行的字符,就需要在正则表达式中加上re.S,例如下面这串代码,div和p标签是不在同一行的,就需要使用re.S,但我实际匹配时,还加上了.*才匹配上,也不清楚是不是多了什么,但目的达到了。
findExcerpt = re.compile(r'<div class="entry excerpt">.*<p>(.*)</p>', re.S)
此外,还有出现源代码与实际html差别很大的问题,例如下面这串代码,在查看源代码时src后面跟的是class,但匹配时发现html文本中class的位置是在srcset后的,因此换成了srcset。
findImage = re.compile(r'src="(.*)" srcset')
简而言之,匹配这部分还是不难的,出了问题要么查看实际html文本,要么就是 .* 加上去,当然,换行的re.S也是需要注意的。
爬取首页函数getData
对应 # 1 部分代码
虽然首页的链接是mwhls.top,但如果点击了下一页,实际显示的是mwhls.top/page/2,而使用mwhls.top/page/1的效果与mwhls.top一样。
也就是说,如果我们想要在首页翻页,只需要更改网站上的最后的数就好了,因此,使用页数自增与文本拼接,合成出每次查询网页的链接。
# 2
askUrl()函数是前文写好的,这里就不重复了,大意就是获取html文本,使用文件open也可以,获取html文本的目的达到就可以了。
# 3
这里的if语句是用来结束循环的,因为作为一个非常勤快的强者,我今天虽然只有三页的博文,但是十年后也许就有四页了,因此还是需要一个通用的语句来判断是否全部查询完。
在实际使用中,如果出现404页面,askUrl函数并不会对html文件进行赋值,因此html文件还保留在“”的状态下。
也就是说,如果html==“”,那么就能够判断已经将所有页面都遍历完了,可以结束循环了。
# 4
这部分的内容,BeautifulSoup的用法,以及re库的用法,前几篇文章讲过了,可以说只要上手用一下就知道大致用法了。
唯一不同的就是概述部分将换行符替换replace,这是因为在实际获取时,有的文章概述中有换行符,在html中换行符是<br/>,将<br/>替换掉就好了,即使不替换,到时候输出数据的时候也会发现这里会多出<br/>,所以不是大问题。
# 5
这个函数看下方的getPostData,是用来获取页面内内容的,可有可无。
# 6
这里的目的是将整理好的数据打印出来,就是个纠错用法,不需要可以直接删掉。
爬取页面内数据getPageData
这个函数实际上就是上一个函数getData的简化版,只获取某一特定页面的特定数据。
这个函数除了提供数据获取框架外,还是为了获取阅读数,因为首页没有显示阅读数,所以需要进入页面爬取。
函数内的各种用法也都在前面提到了,没有什么比较特别的。
共有 0 条评论