Python爬虫之爬取慕课网课程评分

BS是什么?

BeautifulSoup是一个基于标签的文本解析工具。可以根据标签提取想要的内容,很适合处理html和xml这类语言文本。如果你希望了解更多关于BS的介绍和用法,请看BeautifulSoup 4 官方文档

为什么要用BS?

BS可以和许多框架配合使用,让我们在编写爬虫程序时关注于操作逻辑,而不需要再关心其具体实现,最直观地体现就是不需要再编写正则表达式去匹配文本。

如何使用BS?

现在正式开始今天的主要内容:如何使用BS爬取慕课网所有课程及其对应的评分。本文依托的Python环境为Python 3.6.0,pip版本为pip3,BS版本为BS4。

要使用BS,首先需要安装BS:

pip3 install BeautifulSoup4

同时需要获取网页文本,需要安装request:

pip3 install request

接着来分析慕课网的网页结构:

可以看到每一门课都对应一个简单的网址,如"JAVA遇见HTML——Servlet篇"课程对应的网址为:http://www.imooc.com/learn/269 。且目前的最大课程编号为888,因此这里可以用一个简单的循环获得所有课程链接:

baseUrl = "http://www.imooc.com/learn/"
k = 0
while k < 1000:
    url = baseUrl + str(k)

JAVA遇见HTML——Servlet篇中打开开发者视图,可以看到负责课程名称的内容在如下元素中:

<div class="hd clearfix">
	<h2 class="l">JAVA遇见HTML——Servlet篇</h2>
</div>

负责课程评分等信息的内容在如下元素中:

<div class="statics clearfix">
	<div class="moco-btn l learn-btn green-btn red-btn"> 
	<a href="/video/5534" class="J-learn-course">开始学习</a>
	<em></em>
                <i class="follow-action js-follow-action icon-star_outline" data-cid="269" data-cmd="follow" title="收藏"></i>
            </div>           
            <div class="static-item l">
                <span class="meta">学习人数</span>
                <span class="meta-value js-learn-num">111926</span>
                            </div>
            <div class="static-item l">
                <span class="meta">难度级别</span>
                <span class="meta-value">初级</span>
                <em></em>
            </div>
            <div class="static-item l">
                <span class="meta">课程时长</span>
                <span class="meta-value"> 3小时10分</span>
                <em></em>
            </div>
            <div class="static-item l score-btn">
                <span class="meta">综合评分</span>
                <span class="meta-value">9.6</span>
                <em></em>
            </div>
        </div>

这两部分内容包含了我们所有想要获得的信息,下面就可以使用BS4对页面进行处理了。

利用request获取该课程页面的网页源码:

def GetHtmlContext(url):
    try:
        f = request.urlopen(url)
        data = f.read()
        return data
    '如果链接对应的内容不存在,返回0'
    except:
        return 0

获得源码后就可以使用BS4对网页标签进行解析了,上面已经给出了想要获得信息的界面结构,因此可以轻易地完成解析:

def GetData(html, url):
    data = []
    soup = BeautifulSoup(html, "html.parser")

    title = soup.find('div', attrs={'class': 'hd clearfix'})
    data.append(title.find('h2', attrs={'class': 'l'}).getText())
    lesson = soup.find('div', attrs={'class': 'statics clearfix'})

    for attr in lesson.find_all('div', attrs={'class': 'static-item l'}):
        data.append(attr.find('span', attrs={'class': 'meta-value'}).getText())
    grade = lesson.find('div', attrs={'class': 'static-item l score-btn'})
    data.append(grade.find('span', attrs={'class': 'meta-value'}).getText())
    data.append(url)
    data.remove('')

这里不仅获取了课程评分,还获取了课程难度,课程时长以及对应的链接。

完整的代码示例如下:

"""
爬取imooc网站评分过9的课程名称及课程链接等信息
"""
import sys
from urllib import request

from bs4 import BeautifulSoup


def GetHtmlContext(url):
    try:
        f = request.urlopen(url)
        data = f.read()
        return data
    except:
        return 0


def GetData(html, url):

    data = []
    soup = BeautifulSoup(html, "html.parser")

    title = soup.find('div', attrs={'class': 'hd clearfix'})
    data.append(title.find('h2', attrs={'class': 'l'}).getText())
    lesson = soup.find('div', attrs={'class': 'statics clearfix'})

    for attr in lesson.find_all('div', attrs={'class': 'static-item l'}):
        data.append(attr.find('span', attrs={'class': 'meta-value'}).getText())
    grade = lesson.find('div', attrs={'class': 'static-item l score-btn'})
    data.append(grade.find('span', attrs={'class': 'meta-value'}).getText())
    data.append(url)
    data.remove('')
    print(outputMode.format(data[0], data[1], data[2], data[3], data[4], chr(12288)))


# 将输出重定向到txt文件
output = sys.stdout
outputfile = open("D:\lessondata.txt", 'w', encoding='utf-8')
sys.stdout = outputfile


outputMode = "{0:{5}^20}\t{1:^10}\t{2:^10}\t{3:^10}\t{4:{5}<10}"
print(outputMode.format('课程名称', '难度', '课程时长', '综合评分', '课程链接', chr(12288)))
baseUrl = "http://www.imooc.com/learn/"
k = 0
while k < 1000:
    url = baseUrl + str(k)
    html = GetHtmlContext(url)
    k += 1
    if(html != 0):
        GetData(html, url)

outputfile.close()
sys.stdout = output

最后输出结果:

当然你可以也将数据输出到xml文件或数据库,那样更加便于查看和分析,这里就不详细描述了。

参考资料

posted @ 2017-09-24 18:11  deyken  阅读(1665)  评论(0编辑  收藏  举报