天天看点

使用python3.7爬取豆瓣电影top250信息

文章目录

    • 一、准备工作
    • 1.安装python3.7
    • 2.安装爬取豆瓣top250所需包
    • 二、爬取网页
    • 1.分析网页
    • 2.爬取网页
    • 3.信息筛选
    • 4.复制整个网页的xpath路径
    • 5.获取第一页每个电影的名字
    • 6.获取链接
    • 7.评分
    • 8.评价人数
    • 9.排名
    • 10.美化
    • 11用正则表达式re匹配星级数中的数字
    • 12.写入文件夹

一、准备工作

1.安装python3.7

打开浏览器搜索python,得到如下结果:

使用python3.7爬取豆瓣电影top250信息

打开图片中箭头网址

或直接访问python官网打开得到以下画面

使用python3.7爬取豆瓣电影top250信息

下拉网页

使用python3.7爬取豆瓣电影top250信息

选择自己需要的版本

点击后面的download即可下载。

具体安装可以参考其他博友文章,这里不进行过多赘述。

2.安装爬取豆瓣top250所需包

所需要的包有,jupyter(个人习惯的编辑环境,可以不安装)、re(正则表达式)、request、lxml、csv

安装所需包的过程:电脑键盘按住win+R,打开控制台,输入cmd,点击确定或回车啊。

使用python3.7爬取豆瓣电影top250信息

安装包的公式为pip install ******

以安装第一个包为例,输入pip install jupyter,回车,就可以在线安装了

使用python3.7爬取豆瓣电影top250信息

初次安装会需要一些时间,耐心等待一会,其他的包同理。

二、爬取网页

1.分析网页

在此处我们爬取豆瓣电影top250的电影信息

打开可以看到网页如下

使用python3.7爬取豆瓣电影top250信息

我们可以看到本页只有25部电影,我们的任务是爬取250部电影,共十页,分析每一页的区别,此处打开前三页和最后一页的网址对比

第一页

https://movie.douban.com/top250?start=0&filter=

第二页

https://movie.douban.com/top250?start=25&filter=

第三页

https://movie.douban.com/top250?start=50&filter=

最后一页(第十页)

https://movie.douban.com/top250?start=225&filter=

由分析我们可以知道,每一页的网址是差不多的,唯一的差别就是数字的变动,每一页的数值变化为25,

使用python3.7爬取豆瓣电影top250信息

除此之外,其余部分都是一样的。我们可以用一个for循环数组代码来实现这个网页

运用range函数,可以得到十个间隔为25的数组

使用python3.7爬取豆瓣电影top250信息

此处的是226,而不是225是因为range函数后面的括号为前闭后开区间,即为前可取后不可取,三个数字代表的含义分别为从0开始,到226结束,间隔25.

将start=0改为start=%s,后面跟的%page表示将page函数中的数 值范围赋予给s,即可一次性构造出十个网页的链接,代码如下:

for page in range(0, 226, 25):
    url = 'https://movie.douban.com/top250?start=%s&filter='%page
    print (url)
           

运行代码可以得到如下图结果:

使用python3.7爬取豆瓣电影top250信息

至此,我们已经得到了十个网页的代码了。

2.爬取网页

打开豆瓣网页,对网页进行审查,

右击进入检查元素,点击网络(network),再点击所有(All)

对该网页进行刷新,下方会出现网页的组成元素,例如图片等

使用python3.7爬取豆瓣电影top250信息

用箭头标出来的分别为请求方法和状态码,即我们使用的方法为get,返回的状态码为200则为成功,返回其他数值则不成功。

使用get语句访问浏览器,得到如下结果,意义为:系统识别出为非正常访问,拒绝返回值

使用python3.7爬取豆瓣电影top250信息

此处我们需要伪装浏览器,用以躲过网站的识别,首先,讲代码审查中的用户代理复制过来,构造字典,用户代理的位置为:

使用python3.7爬取豆瓣电影top250信息

豆瓣top250中右键检查,notework,all,下拉导航,出现的

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36

即为用户代理。

import requests
test_url = 'https://movie.douban.com/top250?start=0&filter=' 
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}
requests.get(url=test_url,headers=headers)
           

运行即可得到状态码为200的返回值

使用python3.7爬取豆瓣电影top250信息

在代码后加入.text,即可得到以下内容。

使用python3.7爬取豆瓣电影top250信息

我们可以看到,我们虽然成功得爬取了网页数据,不过看上去是很杂乱的,我们还需要筛选数据。

我们加上一句代码

reponse=requests.get(url=test_url,headers=headers).text
#中间一行空格
reponse
           

3.信息筛选

工具:xpath,re,BeautifulSoup,工具需要提前安装,安装教程查看本文开头目录,这里不做过多赘述。

假如我要从网页信息中筛选出“这个杀手不太冷”的电影的名字

使用python3.7爬取豆瓣电影top250信息
#从lxml包里面到处etree这个工具
from lxml import etree  
#使用etree解析网页
html_etree = etree.HTML (reponse)    
#定位 
html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li[4]/div/div[2]/div[1]/a/span[1]/text()')
           

得到如下结果

使用python3.7爬取豆瓣电影top250信息

网页检查中的定位怎么查找:打开网页,找到你想查找的数据,点击检查,在出现的代码中找到你所选择的内容,右键copy xpath。在xpath后面添加/ text()后缀即可查找。

4.复制整个网页的xpath路径

打开网页,右击检查元素,找到每个电影模块对应的序列代码,如下图

使用python3.7爬取豆瓣电影top250信息

将图中右侧鼠标选中的位置的xpath路径复制下来为:

第一个://[@id=“content”]/div/div[1]/ol/li[1]

第二个://[@id=“content”]/div/div[1]/ol/li[2]

第三个://*[@id=“content”]/div/div[1]/ol/li[3]

我们可以分析,每一部电影的结构都大致相似,只有最后的数字不一样。

将上面的代码表示出来为

html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li[1]')

html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li[2]')

html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li[3]')

将最后的[数字]删除,即可表示所有的xpath路径。即

html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li')

可以表示所有的路径。

使用python3.7爬取豆瓣电影top250信息

输入len(li)即可查看路径长度

使用python3.7爬取豆瓣电影top250信息

5.获取第一页每个电影的名字

item可以自己命名,name为电影名字,可自己命名

整个语句可理解为,从25个xpath路径里面获取得250个电影,然后再从这250个电影(item)的xpath路径里面获取250个电影名(name)

第一个://[@id=“content”]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1]

第二个://[@id=“content”]/div/div[1]/ol/li[2]/div/div[2]/div[1]/a/span[1]

可看出,两个链接只有/li[]中的数字不一样,

from lxml import etree html_etree = etree.HTML (reponse) li=html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li') for item in li: name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()') print(name)

得到如下结果:

使用python3.7爬取豆瓣电影top250信息

后面加上[0],可以得到

使用python3.7爬取豆瓣电影top250信息

6.获取链接

对电影的链接进行分析

第一个://[@id=“content”]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a

第二个://[@id=“content”]/div/div[1]/ol/li[2]/div/div[2]/div[1]/a

只有li[]不一样,其他的都是一样的,做法同上一个获取电影名称

代码如下:

from lxml import etree  
html_etree = etree.HTML (reponse)  
li=html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
for item in li:
    name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()')
    print(name)
    dy_url = item.xpath('./div/div[2]/div[1]/a/@href')
    print(dy_url)
           

运行:

使用python3.7爬取豆瓣电影top250信息

7.评分

第一个://[@id=“content”]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[1]

第二个://[@id=“content”]/div/div[1]/ol/li[2]/div/div[2]/div[2]/div/span[1]

同理,代码不一样

from lxml import etree  
html_etree = etree.HTML (reponse)  
li=html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
for item in li:
    name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()')
    print(name)
    dy_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
    print (dy_url)
    rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
    print(rating)

           
使用python3.7爬取豆瓣电影top250信息

8.评价人数

第一个://[@id=“content”]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[4]

第二个://[@id=“content”]/div/div[1]/ol/li[2]/div/div[2]/div[2]/div/span[4]

同理:

from lxml import etree  
html_etree = etree.HTML (reponse)  
li=html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
for item in li:
    name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()')
    print(name)
    dy_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
    print (dy_url)
    rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
    print(rating)
    content=item.xpath('./div/div[2]/div[2]/div/span[4]/text()')
    print(content)

           
使用python3.7爬取豆瓣电影top250信息

9.排名

原理同上

使用python3.7爬取豆瓣电影top250信息

10.美化

输入’~’*50, 可以加波浪线,50为个数

使用python3.7爬取豆瓣电影top250信息

11用正则表达式re匹配星级数中的数字

如爬取到的星级数为rating5-t或rating4.5-t,但我们只想要数字,故用正则表达式来匹配

re正则表达式语法较复杂,平时可在网上多学习

准备工作:引入re包,import re

我们首先要知道一些关于正则表达式的使用方法,正则表达式替换的方法是.*?替换。

例如:

import re
a = "123人评价"
re.findall('(.*?)人评价', a)
           

则输出为123.

使用python3.7爬取豆瓣电影top250信息

这样输出的rating分数,还是有一点问题,那就是本来应该是4.5的变为了45,因此我们还需要设置一个条件语句,

if len(rating) == 2:
            star = int(rating) / 10  #int()转化为数字
        else:
            star = rating
           

意义为当rating长度为2的时候,除以十,当rating长度不为2,就不改变。

12.写入文件夹

分为三个步骤,1.创建文件夹并打开

fp = open("./豆瓣top250.csv", 'a', newline='', encoding = 'utf-8-sig') writer = csv.writer(fp)

2.写入

writer.writerow(('排名', '名称', '链接', '星级', '评分', '评价人数'))
writer.writerow((rank, name, dy_url, star, rating_num, content))
           

3.关闭

插入代码中,运行即可

使用python3.7爬取豆瓣电影top250信息

在此处我们看不到文件,返回jupyter文件夹,打开即可看到文件

使用python3.7爬取豆瓣电影top250信息

打开可以看到

使用python3.7爬取豆瓣电影top250信息

至此,我们本次任务完成。

代码汇总:

import requests, csv, re
from lxml import etree

#设置浏览器代理,它是一个字典
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}

# 创建文件夹并打开
fp = open("./豆瓣top250.csv", 'a', newline='', encoding = 'utf-8-sig')
writer = csv.writer(fp) #我要写入
# 写入内容
writer.writerow(('排名', '名称', '链接', '星级', '评分', '评价人数'))

for page in range(0, 226, 25): #226
    print ("正在获取第%s页"%page)
    url = 'https://movie.douban.com/top250?start=%s&filter='%page
    
    #请求源代码,向服务器发出请求,200代表成功,回退对其,Ctrl+]
    reponse = requests.get(url = url, headers = headers).text
    # 快捷键运行,Ctrl+Enter
    html_etree = etree.HTML(reponse) # 看成一个筛子,树状
    # 过滤
    li = html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
    for item in li:
        #排名
        rank = item.xpath('./div/div[1]/em/text()')[0]
        #电影名称
        name = item.xpath('./div/div[2]/div[1]/a/span[1]/text()')[0]
        #链接
        dy_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
    #     print (dy_url)
        #评分
        rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
        rating = re.findall('rating(.*?)-t', rating)[0]
        if len(rating) == 2:
            star = int(rating) / 10  #int()转化为数字
        else:
            star = rating
    #     注释ctrl+?

        rating_num = item.xpath('./div/div[2]/div[2]/div/span[2]/text()')[0]
        content = item.xpath('./div/div[2]/div[2]/div/span[4]/text()')[0]
        content = re.sub(r'\D', "", content)
#         print (rank, name, dy_url, star, rating_num, content)
        # 写入内容
        writer.writerow((rank, name, dy_url, star, rating_num, content))
fp.close()
           

通过本次作业,想说的是,自己不够认真,很多处小错误,然后查找错误花费了很多时间,一些问题自己无法解决,参考了同学的作业,总的来说需要多从实战之中获取经验。这次辛苦杨友同学老师了。