WHCSRL 技术网

Python爬虫简单教程

Python爬虫实战笔记

完整源码

# codeing = utf-8

# 引入模块
import urllib.request, urllib.error  # 制定URL,获取网页数据
from bs4 import BeautifulSoup  # 网页解析
import sqlite3  # 进行SQLite数据库操作
import xlwt  # 进行excel操作
import re  # 正则表达式



def main():
    baseurl = 'https://movie.douban.com/top250?start='  # 设置基础网页链接
    savepath = '.\豆瓣电影Top250.xls'  # 保存解析后数据的文件
    # 1.爬取网页
    datalist = getData(baseurl)

    # 3.保存数据
    savaData(datalist,savepath)



# 全局变量
#  创建正则表达式对象(字符串模式),规则
# 	影片详情链接规则
findLink = re.compile(r'<a href="(.*?)">')
# 	影片图片链接规则
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S)   # re.S 让换行符包含在字符中
# 	影片片名规则
findTitle = re.compile(r'<span class="title">(.*)</span>')
# 	影片评分规则
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
# 	影片评价人数
findJudge = re.compile(r'<span>(d*)人评价</span>')
# 	影片概况规则
findInq = re.compile(r'<span class="inq">(.*)</span>')
# 	影片相关内容规则
findBd = re.compile(r'<p class="">(.*?)</p>', re.S)



# 爬取网页
def getData(baseurl):
    datalist = []
    for i in range(0, 10):  # 调用获取页面信息的函数,10次
        url = baseurl + str(i * 25)
        html = askURL(url)  # 保存获取到的网页源码
        #print(html)

        # 2.解析数据
        soup = BeautifulSoup(html,"html.parser")         # 设置解释器
        for item in soup.find_all('div', class_='item'): # 查找符合要求的字符串,形成列表
            #print(item)
            data = [];  # 保存一部电影的所有信息
            item = str(item)

            # 获取影片详情链接
            link = re.findall(findLink, item)[0]    # re库通过正则表达式查找指定字符串
            data.append(link)                       # 添加链接

            imgSrc = re.findall(findImgSrc,item)[0]
            data.append(imgSrc)                     # 添加图片

            titles = re.findall(findTitle,item)     # 片名可能只有一个
            if(len(titles) == 2):   # 若存在其他名字
                ctitle = titles[0]
                data.append(ctitle)                 # 添加中文名
                otitle = titles[1].replace("/","")  # 去掉无关的符号
                data.append(otitle)                 # 添加别名(外国名)
            else:                   # 只有一个片名
                data.append(titles[0])              # 添加中文名
                data.append(" ")                    # 留空

            rating = re.findall(findRating,item)[0]
            data.append(rating)                     # 添加评分

            judgeNum = re.findall(findJudge,item)[0]
            data.append(judgeNum)                   # 添加评价人数

            inq = re.findall(findInq,item)
            if len(inq) != 0:
                inq = inq[0].replace("。","")       # 去掉句号
                data.append(inq)                    # 添加概述
            else:
                data.append(" ")                    # 留空

            bd = re.findall(findBd,item)[0]
            bd = re.sub('<br(s+)?/>(s+)?'," ",bd) # 去掉<br/>
            bd = re.sub('/'," ",bd)                 # 替换/
            data.append(bd.strip())                 # 添加相关信息 | .strip() 去掉前后空格

            datalist.append(data)                   # 把处理好的一部电影信息放入datalist

    return datalist



# 得到指定一个URL的网页内容
def askURL(url):
    head = {  # 用户代理,表示告诉豆瓣服务器,我们是什么类型的机器(这个是我们模拟的,伪装用)
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/94.0.4606.81 Safari/537.36'
    }
    # 合成请求报头
    request = urllib.request.Request(url, headers=head)
    html = ''
    try:
        # 发送请求
        response = urllib.request.urlopen(request)
        # 保存获取的网页源码
        html = response.read().decode('utf-8')
    except urllib.error.URLError as e:  # 异常处理
        if hasattr(e, 'code'):
            print(e.code)
        if hasattr(e, 'reason'):
            print(e.reason)

    return html



# 保存数据
def savaData(datalist, savepath):
    print("save...")
    book = xlwt.Workbook(encoding="utf-8",style_compression=0)     # 创建workbook对象
    sheet = book.add_sheet('豆瓣电影Top250',cell_overwrite_ok=True) # 创建工作表
    col = ("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概述","相关信息")
    for i in range(0,8):
        sheet.write(0,i,col[i]) # 列名
    for i in range(0,250):
        print("第%%d条"%%(i+1))
        data = datalist[i]  # 第i 条电影
        for j in range(0,8):
            sheet.write(i+1, j, data[j])

    book.save(savepath) # 保存



if __name__ == '__main__':
    main()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141

准备工作

我们的目标是把豆瓣Top250 的影片信息爬取到到Excel 中。

目标网站

豆瓣电影 Top 250

URL分析

我们可以看到它的链接是:https://movie.douban.com/top250

划到最下面,选择后页,再选择前页,我们就可以看到网页的参数列表:https://movie.douban.com/top250?start=0&filter=

参数有:start 和 filter(过滤器,这里没有值,所以其实是可以忽略的)

现在再点击后页,看到链接:https://movie.douban.com/top250?start=25&filter=

可以看到变化的是 start,从0 变成了25,现在我们就能明白,start参数是让榜单从 start+1 开始往后呈现,动动手把start 传入的值改为任意一个在0~249 内的数试试看效果吧。

最后,我们简化链接,明确只需要改变start 的值就可以了:https://movie.douban.com/top250?start=0

页面分析

  1. 访问我们分析后的URL,然后 右键查看页面源代码,按以下三步找到我们页面元素的位置

在这里插入图片描述

  1. 之后找到Network(网络),打开以下页面。

Headers

在这里插入图片描述

这个是我们给服务器发送的请求。

Response

在这里插入图片描述

这个是服务器响应我们请求的数据。

引入模块

# 引入模块
from bs4 import BeautifulSoup      #网页解析
import re  		#正则表达式
import urllib.request,urllib.error #制定URL,获取网页数据
import xlwt     #进行excel操作
import sqlite3  #进行SQLite数据库操作
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果写完出现红色波浪线说明这个模块你是没有安装的,可以按以下步骤安装。

在这里插入图片描述

  1. 更新pip:pip install --upgrade pip
  2. 下载 bs4:pip install bs4
  3. 下载xlwt:pip install xlwt

获取数据

# codeing = utf-8

# 引入模块
import urllib.request, urllib.error  # 制定URL,获取网页数据
from bs4 import BeautifulSoup  # 网页解析
import sqlite3  # 进行SQLite数据库操作
import xlwt  # 进行excel操作
import re  # 正则表达式



def main():
    baseurl = 'https://movie.douban.com/top250?start='  # 设置基础网页链接
    savepath = '.\豆瓣电影Top250.xls'  # 保存解析后数据的文件
    # 1.爬取网页
    datalist = getData(baseurl)

    # 3.保存数据
    # savaData(datalist, savepath)



# 爬取网页
def getData(baseurl):
    datalist = []
    for i in range(0, 10):  # 调用获取页面信息的函数,10次
        url = baseurl + str(i * 25)
        html = askURL(url)  # 保存获取到的网页源码
        print(html)
        # 2.解析数据

    return datalist



# 得到指定一个URL的网页内容
def askURL(url):
    head = {  # 用户代理,表示告诉豆瓣服务器,我们是什么类型的机器(这个是我们模拟的,伪装用)
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/94.0.4606.81 Safari/537.36'
    }
    # 合成请求报头
    request = urllib.request.Request(url, headers=head)
    html = ''
    try:
        # 发送请求
        response = urllib.request.urlopen(request)
        # 保存获取的网页源码
        html = response.read().decode('utf-8')
    except urllib.error.URLError as e:  # 异常处理
        if hasattr(e, 'code'):
            print(e.code)
        if hasattr(e, 'reason'):
            print(e.reason)

    return html



# 保存数据
def savaData(datalist, savepath):
    pass



if __name__ == '__main__':
    main()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

目前打印出来的就是所有 html数据,接下来我们来分析数据并解析。

解析内容

分析html

看看官方网页我们需要提取的 html标签:

<div class="item">
<div class="pic">
<em class="">1</em>
<a href="https://movie.douban.com/subject/1292052/">
<img alt="肖申克的救赎" class="" src="https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg" width="100"/>
</a>
</div>
<div class="info">
<div class="hd">
<a class="" href="https://movie.douban.com/subject/1292052/">
<span class="title">肖申克的救赎</span>
<span class="title"> / The Shawshank Redemption</span>
<span class="other"> / 月黑高飞(港)  /  刺激1995(台)</span>
</a>
<span class="playable">[可播放]</span>
</div>
<div class="bd">
<p class="">
                            导演: 弗兰克·德拉邦特 Frank Darabont   主演: 蒂姆·罗宾斯 Tim Robbins /...<br/>
                            1994 / 美国 / 犯罪 剧情
                        </p>
<div class="star">
<span class="rating5-t"></span>
<span class="rating_num" property="v:average">9.7</span>
<span content="10.0" property="v:best"></span>
<span>2472032人评价</span>
</div>
<p class="quote">
<span class="inq">希望让人自由。</span>
</p>
</div>
</div>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

获取html

可以用:

# 2.解析数据
soup = BeautifulSoup(html,"html.parser") # 设置解释器
        for item in soup.find_all('div', class_='item'): # 查找符合要求的字符串,形成列表
            print(item)
  • 1
  • 2
  • 3
  • 4

来获取到它。

设置正则

接下来我们就可以循环拆解出来我们需要的内容,那么我们先把其他要获取的正则表达式规则都写出来:

# 全局变量
#  创建正则表达式对象(字符串模式),规则
# 	影片详情链接规则
findLink = re.compile(r'<a href="(.*?)">')
# 	影片图片链接规则
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S)   # re.S 让换行符包含在字符中
# 	影片片名规则
findTitle = re.compile(r'<span class="title">(.*)</span>')
# 	影片评分规则
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
# 	影片评价人数
findJudge = re.compile(r'<span>(d*)人评价</span>')
# 	影片概况规则
findInq = re.compile(r'<span class="inq">(.*)</span>')
# 	影片相关内容规则
findBd = re.compile(r'<p class="">(.*?)</p>', re.S)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

正则解析数据

然后将解析数据的代码完善好:

# 爬取网页
def getData(baseurl):
    datalist = []
    for i in range(0, 10):  # 调用获取页面信息的函数,10次
        url = baseurl + str(i * 25)
        html = askURL(url)  # 保存获取到的网页源码
        #print(html)

        # 2.解析数据
        soup = BeautifulSoup(html,"html.parser")         # 设置解释器
        for item in soup.find_all('div', class_='item'): # 查找符合要求的字符串,形成列表
            #print(item)
            data = [];  # 保存一部电影的所有信息
            item = str(item)

            # 获取影片详情链接
            link = re.findall(findLink, item)[0]    # re库通过正则表达式查找指定字符串
            data.append(link)                       # 添加链接

            imgSrc = re.findall(findImgSrc,item)[0]
            data.append(imgSrc)                     # 添加图片

            titles = re.findall(findTitle,item)     # 片名可能只有一个
            if(len(titles) == 2):   # 若存在其他名字
                ctitle = titles[0]
                data.append(ctitle)                 # 添加中文名
                otitle = titles[1].replace("/","")  # 去掉无关的符号
                data.append(otitle)                 # 添加别名(外国名)
            else:                   # 只有一个片名
                data.append(titles[0])              # 添加中文名
                data.append(" ")                    # 留空

            rating = re.findall(findRating,item)[0]
            data.append(rating)                     # 添加评分

            judgeNum = re.findall(findJudge,item)[0]
            data.append(judgeNum)                   # 添加评价人数

            inq = re.findall(findInq,item)
            if len(inq) != 0:
                inq = inq[0].replace("。","")       # 去掉句号
                data.append(inq)                    # 添加概述
            else:
                data.append(" ")                    # 留空

            bd = re.findall(findBd,item)[0]
            bd = re.sub('<br(s+)?/>(s+)?'," ",bd) # 去掉<br/>
            bd = re.sub('/'," ",bd)                 # 替换/
            data.append(bd.strip())                 # 添加相关信息 | .strip() 去掉前后空格

            datalist.append(data)                   # 把处理好的一部电影信息放入datalist

    return datalist
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

数据演示

获取到的数据datalist 大致为:(列表内包含列表)

[['https://movie.douban.com/subject/1292052/', 'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg', '肖申克的救赎', 'xa0xa0The Shawshank Redemption', '9.7', '2475783', '希望让人自由', '导演: 弗兰克·德拉邦特 Frank Darabontxa0xa0xa0主演: 蒂姆·罗宾斯 Tim Robbins  ... 1994xa0 xa0美国xa0 xa0犯罪 剧情'], ['https://movie.douban.com/subject/1291546/', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2561716440.jpg', '霸王别姬', ' ', '9.6', '1840336', '风华绝代', '导演: 陈凯歌 Kaige Chenxa0xa0xa0主演: 张国荣 Leslie Cheung   张丰毅 Fengyi Zha... 1993xa0 xa0中国大陆 中国香港xa0 xa0剧情 爱情 同性']]
  • 1

保存数据

下面我们来把我们爬取到的数据保存到Excel 中。

# 保存数据
def savaData(datalist, savepath):
    print("save...")
    book = xlwt.Workbook(encoding="utf-8",style_compression=0)     # 创建workbook对象
    sheet = book.add_sheet('豆瓣电影Top250',cell_overwrite_ok=True) # 创建工作表
    col = ("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概述","相关信息")
    for i in range(0,8):
        sheet.write(0,i,col[i]) # 列名
    for i in range(0,250):
        print("第%%d条" %%i)
        data = datalist[i]  # 第i 条电影
        for j in range(0,8):
            sheet.write(i+1, j, data[j])

    book.save(savepath) # 保存
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

效果展示

最后程序运行后得到豆瓣电影Top250.xls,效果如下:
在这里插入图片描述

推荐阅读