python爬取豆瓣top250

1.分析并获取url链接

豆瓣top250榜单共有10页,每页有25部电影,找到url链接中的规律如下:
在这里插入图片描述
即数字相差为25,用for循环生成链接如下:
在这里插入图片描述
即得到了我们要爬取的所有链接(以上只截取部分)。

2.请求服务器

2.1 设置浏览器代理:网页空白处单击鼠标右键,点击检查,选择Network,All,刷新网页后双击第一个文件,选择headers,下拉到最底部复制如下内容:在这里插入图片描述
设置的浏览器代理为字典型:

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'
}

2.2请求服务器格式及内容:

  • 请求源代码,向服务器发出请求,显示‘200’代表成功。
  • 在后面加上 .text 表示输出文本内容。
  • 第二个 url 是使用的链接,第二个 headers 是用来做浏览器代理的内容。

2.3请求服务器代码:

import requests
url='https://movie.douban.com/top250?start=%s&filter='%page
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'
}
reponse = requests.get(url = url, headers = headers).text

3.xpath提取信息

3.1获取xpath节点
在这里插入图片描述
3.2 xpath提取内容

from lxml import etree
html_etree = etree.HTML(reponse)

3.2.1 提取文本
当我们提取标签内的文本时,需要在复制到的xpath后面加上/text() ,告诉它需要提取的内容是此标签所呈现的文本或数据,如电影排名+《肖申克的救赎》所要提取xpath的代码为:

<em class="">1</em>
<span class="title">肖申克的救赎</span>

xpath分别为:

//*[@id="content"]/div/div[1]/ol/li[1]/div/div[1]/em
//*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/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:
    #电影排名
    rank = item.xpath('./div/div[1]/em/text()')[0]
    #电影名称
    name = item.xpath('./div/div[2]/div[1]/a/span[1]/text()')[0]
    print (rank,name)

注:li 标签前面的作为父级,后面的为子集,用./ 代替父级的位置,所以改写为:

rank = item.xpath('./div/div[1]/em/text()')[0]
name = item.xpath('./div/div[2]/div[1]/a/span[1]/text()')[0]

结果为:

'1 肖申克的救赎'

*其中代码最后加的[0]表示字符串形式,不加[0]表示数组形式。分别表示为:

字符串形式: 1 肖申克的救赎
数组形式: ['1 肖申克的救赎']

3.2.2 提取链接
每一个链接都是在标签内的,通常放在src=" " 或者 href=" " 之中,如:
在a标签中

xpath为:

//*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a

提取链接:提取链接时,需要在复制到的xpath后面加上/@href , 指定提取链接:

#电影链接
movie_url = html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/@href')[0]
print (movie_url)

提取结果:

https://movie.douban.com/subject/1292052/

3.2.3 提取星级、评分、评价人数
这个网页中电影的星级没有用文本表示,而是用标签表示的,如:
在这里插入图片描述
所以只需要提取出 class=" "中的内容就可以得到相对应的星级了。复制它的xpath,和提取链接的方法一样,在后面加上 /@class 即可;提取评分和评价人数的方法与提取电影名称的方法一样,在后面加上/text()即可,如:

    #电影星级
    rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
    print(rating)
    #电影评分
    rating_num = item.xpath('./div/div[2]/div[2]/div/span[2]/text()')[0]
    print(rating_num)
    #电影评价人数
    content = item.xpath('./div/div[2]/div[2]/div/span[4]/text()')[0]
    print(content)

提取结果分别为:

rating5-t
9.7
1973359人评价

4.正则表达式匹配信息

如需把结果中的信息匹配出来,可以使用正则表达式把它提取出来。因为它是以 rating5-t 等方式呈现的,我们只需要它数字‘5’的部分,所以需要进行二次提取。
4.1、提取固定位置信息
正则表达式中可以使用 .*? 来进行匹配信息,在需要提取固定位置信息的地方加上一个括号 (.*?) 可以提取出括号内的内容,如:

import re
test = "rating5-t"
text = re.findall('rating(.*?)-t', test)
print (text)

运行结果为:

['5']

4.2、匹配出数字
电影评价人数,xpath提取到的数据格式为:1056830人评价 ,保存的时候只需要数字,所以要把数字提取出来:

import re 
data = "1059232人评价"
num = re.sub(r'\D', "", data)
print("这里的数字是:", num)

运行结果:

1059232

5、提取所有信息

综合以上代码,汇总为:

import requests
import re
from lxml import etree
#设置浏览器代理
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'
}

    # 请求源代码,向服务器发出请求,200代表成功
    reponse = requests.get(url = url, headers = headers).text
    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]
        #电影链接
        movie_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
        #电影星级
        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
        else:
            star = rating
        #电影评分
        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,movie_url,star,rating_num,content)

运行结果为(截取第一页为例):

1 肖申克的救赎 https://movie.douban.com/subject/1292052/ 5 9.7 1974974
2 霸王别姬 https://movie.douban.com/subject/1291546/ 5 9.6 1460983
3 阿甘正传 https://movie.douban.com/subject/1292720/ 5 9.5 1497788
4 这个杀手不太冷 https://movie.douban.com/subject/1295644/ 4.5 9.4 1691633
5 美丽人生 https://movie.douban.com/subject/1292063/ 5 9.5 945115
6 泰坦尼克号 https://movie.douban.com/subject/1292722/ 4.5 9.4 1445256
7 千与千寻 https://movie.douban.com/subject/1291561/ 4.5 9.4 1545988
8 辛德勒的名单 https://movie.douban.com/subject/1295124/ 5 9.5 763919
9 盗梦空间 https://movie.douban.com/subject/3541415/ 4.5 9.3 1436154
10 忠犬八公的故事 https://movie.douban.com/subject/3011091/ 4.5 9.4 993496
11 海上钢琴师 https://movie.douban.com/subject/1292001/ 4.5 9.3 1195972
12 楚门的世界 https://movie.douban.com/subject/1292064/ 4.5 9.3 1059839
13 三傻大闹宝莱坞 https://movie.douban.com/subject/3793023/ 4.5 9.2 1326770
14 机器人总动员 https://movie.douban.com/subject/2131459/ 4.5 9.3 947087
15 放牛班的春天 https://movie.douban.com/subject/1291549/ 4.5 9.3 923406
16 星际穿越 https://movie.douban.com/subject/1889243/ 4.5 9.3 1066796
17 大话西游之大圣娶亲 https://movie.douban.com/subject/1292213/ 4.5 9.2 1045100
18 熔炉 https://movie.douban.com/subject/5912992/ 4.5 9.3 642609
19 疯狂动物城 https://movie.douban.com/subject/25662329/ 4.5 9.2 1243956
20 无间道 https://movie.douban.com/subject/1307914/ 4.5 9.2 851093
21 龙猫 https://movie.douban.com/subject/1291560/ 4.5 9.2 888995
22 教父 https://movie.douban.com/subject/1291841/ 4.5 9.3 649741
23 当幸福来敲门 https://movie.douban.com/subject/1849031/ 4.5 9.1 1061614
24 怦然心动 https://movie.douban.com/subject/3319755/ 4.5 9.1 1230844
25 触不可及 https://movie.douban.com/subject/6786002/ 4.5 9.2 693600

6、内容写入CSV文件

写入并保存内容分为三步:

  1. 打开文件夹
  2. 写入文件夹
  3. 关闭文件夹
import csv
# 创建文件并打开
fp = open("./豆瓣top250.csv", 'a', newline='', encoding = 'utf-8-sig')
writer = csv.writer(fp)

# 把内容写入文件
writer.writerow(('排名', '名称', '链接', '星级', '评分', '评价人数'))

#关闭文件
fp.close()

7.代码汇总

import requests,re,csv
from lxml import etree
#设置浏览器代理
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'
}
#创建文件夹并打开
fp = open("./豆瓣top250.csv", 'a', newline='', encoding = 'utf-8-sig')
writer = csv.writer(fp)
# 写入内容
writer.writerow(('电影排名', '电影名称', '电影链接', '电影星级', '电影评分', '电影评价人数'))
for page in range(0, 226, 25):
    print ("正在获取第%s页"%page)
    url='https://movie.douban.com/top250?start=%s&filter='%page
    # 请求源代码,向服务器发出请求,200代表成功
    reponse = requests.get(url = url, headers = headers).text
    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]
        #电影链接
        movie_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
        #电影星级
        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
        else:
            star = rating
        #电影评分
        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,movie_url,star,rating_num,content)
        # 写入内容
        writer.writerow((rank,name,movie_url,star,rating_num,content))
#关闭文件夹
fp.close()
jupyter运行截屏

在这里插入图片描述

csv文件截屏

在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值