Python爬虫(四)-截取数据

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的简化版,只获取某一特定页面的特定数据。

这个函数除了提供数据获取框架外,还是为了获取阅读数,因为首页没有显示阅读数,所以需要进入页面爬取。

函数内的各种用法也都在前面提到了,没有什么比较特别的。

You may also like...

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注