XPath实战之爬取豆瓣电影

本文详细介绍了如何使用Python和lxml库爬取豆瓣电影正在热映的电影信息,包括电影标题、评分、上映时间等,并将数据保存为CSV文件。

进入豆瓣电影后点击全部正在热映:

                                

           

然后首先需要将数据请求下来。

一个爬虫基本上都是由两个部分组成的:1、将目标网站上的页面抓取下来,2、将抓取下来的数据根据一定的规则进行提取。

                            

从网页源代码可以看到所有电影信息都在ul标签里的li标签下,因此需要拿到class=lists的ul:

import requests
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',
    #在爬虫里面如果出现了Referer最好也粘上去,因为有时候服务器会根据Referer来判断请求时由浏览器还是爬虫发出的
    'Referer':'https://www.douban.com/'
}
url = 'https://movie.douban.com/cinema/nowplaying/chengdu/'
response = requests.get(url,headers=headers)#发起请求得到响应
text = response.text#返回一个经过解码的字符串
content = response.content#返回原生的没有经过处理的网页,是bytes类型
html = etree.HTML(text)#将其解码
ul = html.xpath("//ul[@class='lists']")
print(ul)
[<Element ul at 0x16b2924e508>, <Element ul at 0x16b2924e488>]

但打印出来看到有两个ul,因此需要判断我们想要的是哪一个ul:

                   

从网页源代码发现除了正在上映的以外还有即将上映的,而我们想要的是第一个,因此使用ul = html.xpath("//ul[@class='lists']")[0]就行了。打印一下就可以看到需要的信息了:print(etree.tostring(ul,encoding='utf-8').decode('utf-8'))。得到了所有电影的信息之后就需要获取每一步电影,通过ul获取所有的li标签:

import requests
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',
    #在爬虫里面如果出现了Referer最好也粘上去,因为有时候服务器会根据Referer来判断请求时由浏览器还是爬虫发出的
    'Referer':'https://www.douban.com/'
}
url = 'https://movie.douban.com/cinema/nowplaying/chengdu/'
response = requests.get(url,headers=headers)#发起请求得到响应
text = response.text#返回一个经过解码的字符串
content = response.content#返回原生的没有经过处理的网页,是bytes类型
html = etree.HTML(text)#将其解码
ul = html.xpath("//ul[@class='lists']")[0]
lis = ul.xpath("./li")
for li in lis:
    print(etree.tostring(li,encoding='utf-8').decode('utf-8'))

                                                        

比如说我们要拿到大黄蜂这个title,通过data-title就可以获取到:

for li in lis:
    title = li.xpath("@data-title")
    print(title)
['大黄蜂']
['一条狗的回家路']
['我想吃掉你的胰脏']
['家和万事惊']
['掠食城市']
['“大”人物']
['白蛇:缘起']
['密室逃生']
['闯堂兔3囧囧时光机']
['钢铁飞龙之奥特曼崛起']
['森林奇缘']
['海王']
['来电狂响']
['四个春天']
['大路朝天']
['蜘蛛侠:平行宇宙']
['燃点']
['命运之夜——天之杯:恶兆之花']
['养家之人']

这样就获取到了所有的title了。

然后取第0个就可以拿到真正的标题了:title = li.xpath("@data-title")[0]

然后用同样的方法拿到其它信息:

import requests
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',
    #在爬虫里面如果出现了Referer最好也粘上去,因为有时候服务器会根据Referer来判断请求时由浏览器还是爬虫发出的
    'Referer':'https://www.douban.com/'
}
url = 'https://movie.douban.com/cinema/nowplaying/chengdu/'
response = requests.get(url,headers=headers)#发起请求得到响应
text = response.text#返回一个经过解码的字符串
content = response.content#返回原生的没有经过处理的网页,是bytes类型
html = etree.HTML(text)#将其解码
ul = html.xpath("//ul[@class='lists']")[0]
lis = ul.xpath("./li")
movies = []#存取电影信息的列表
for li in lis:
    title = li.xpath("@data-title")[0]
    score = li.xpath("@data-score")[0]
    release = li.xpath("@data-release")[0]
    duration = li.xpath("@data-duration")[0]
    region = li.xpath("@data-region")[0]
    director = li.xpath("@data-director")[0]
    actors = li.xpath("@data-actors")[0]
    poster = li.xpath('.//img/@src')[0]#选中当前节点下的所有子孙节点中的img标签获取其中的src属性
    #构造字典
    movie = {
        '标题':title,
        '得分':score,
        '上映时间':release,
        '时长':duration,
        '国家':region,
        '导演':director,
        '演员':actors,
        'poster':poster
    }
    movies.append(movie)
for movie in movies:
    print(movie)
{'标题': '大黄蜂', '得分': '7.2', '上映时间': '2018', '时长': '114分钟', '国家': '美国', '导演': '特拉维斯·奈特', '演员': '海莉·斯坦菲尔德 / 小豪尔赫·兰登伯格 / 约翰·塞纳', 'poster': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2541662397.jpg'}
{'标题': '一条狗的回家路', '得分': '6.7', '上映时间': '2019', '时长': '96分钟', '国家': '美国', '导演': '查尔斯·马丁·史密斯', '演员': '艾什莉·贾德 / 乔纳·豪尔-金 / 亚历山德拉·希普', 'poster': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2545487478.jpg'}
{'标题': '我想吃掉你的胰脏', '得分': '7.0', '上映时间': '2018', '时长': '108分钟', '国家': '日本', '导演': '牛岛新一郎', '演员': '高杉真宙 / Lynn / 藤井雪代', 'poster': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2545571306.jpg'}
{'标题': '家和万事惊', '得分': '7.2', '上映时间': '2019', '时长': '92分钟', '国家': '中国大陆 香港', '导演': '邱礼涛', '演员': '吴镇宇 / 古天乐 / 袁咏仪', 'poster': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2545486388.jpg'}
{'标题': '“大”人物', '得分': '6.7', '上映时间': '2019', '时长': '107分钟', '国家': '中国大陆', '导演': '五百', '演员': '王千源 / 包贝尔 / 王迅', 'poster': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2544988187.jpg'}
{'标题': '白蛇:缘起', '得分': '8.0', '上映时间': '2019', '时长': '95分钟', '国家': '中国大陆 美国', '导演': '黄家康 赵霁', '演员': '张喆 / 杨天翔 / 唐小喜', 'poster': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2544313786.jpg'}
{'标题': '掠食城市', '得分': '6.7', '上映时间': '2018', '时长': '128分钟', '国家': '美国 新西兰', '导演': '克里斯蒂安·瑞沃斯', '演员': '海拉·西尔玛 / 雨果·维文 / 金吉', 'poster': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2543972440.jpg'}
{'标题': '密室逃生', '得分': '7.4', '上映时间': '2019', '时长': '100分钟', '国家': '美国', '导演': '亚当·罗比特尔', '演员': '泰勒·拉塞尔 / 洛根·米勒 / 黛博拉·安沃尔', 'poster': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2543541082.jpg'}
{'标题': '闯堂兔3囧囧时光机', '得分': '0', '上映时间': '2019', '时长': '88分钟', '国家': '中国大陆', '导演': '曾宪林', '演员': '', 'poster': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2545487918.jpg'}
{'标题': '钢铁飞龙之奥特曼崛起', '得分': '0', '上映时间': '2019', '时长': '90分钟', '国家': '中国大陆', '导演': '王巍', '演员': '', 'poster': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2544885346.jpg'}
{'标题': '森林奇缘', '得分': '0', '上映时间': '2018', '时长': '91分钟', '国家': '乌克兰', '导演': '奥列格·马拉姆兹', '演员': 'Nadezhda Dorofeeva / Aleksey Zavgorodniy / Yevhen Malukha', 'poster': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2542552017.jpg'}
{'标题': '海王', '得分': '7.8', '上映时间': '2018', '时长': '143分钟', '国家': '美国 澳大利亚', '导演': '温子仁', '演员': '杰森·莫玛 / 艾梅柏·希尔德 / 威廉·达福', 'poster': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2541280047.jpg'}
{'标题': '来电狂响', '得分': '6.0', '上映时间': '2018', '时长': '103分钟', '国家': '中国大陆', '导演': '于淼', '演员': '佟大为 / 马丽 / 霍思燕', 'poster': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2542268337.jpg'}
{'标题': '大路朝天', '得分': '0', '上映时间': '2018', '时长': '120分钟', '国家': '中国大陆', '导演': '苗月', '演员': '李保田 / 陈瑾 / 巴登西绕', 'poster': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2543162197.jpg'}
{'标题': '四个春天', '得分': '8.9', '上映时间': '2017', '时长': '105分钟', '国家': '中国大陆', '导演': '陆庆屹', '演员': '陆运坤 / 李桂贤', 'poster': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2540578887.jpg'}
{'标题': '蜘蛛侠:平行宇宙', '得分': '8.7', '上映时间': '2018', '时长': '116分钟(中国大陆)', '国家': '美国', '导演': '鲍勃·佩尔西凯蒂 彼得·拉姆齐 罗德尼·罗斯曼', '演员': '沙梅克·摩尔 / 杰克·约翰逊 / 海莉·斯坦菲尔德', 'poster': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2542867516.jpg'}
{'标题': '燃点', '得分': '5.9', '上映时间': '2019', '时长': '107分钟', '国家': '中国大陆', '导演': '关琇 萧屺楠', '演员': '罗永浩 / 戴威 / 张颖', 'poster': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2541278708.jpg'}
{'标题': '命运之夜——天之杯:恶兆之花', '得分': '7.6', '上映时间': '2017', '时长': '119分钟(中国大陆)', '国家': '日本', '导演': '须藤友德', '演员': '杉山纪彰 / 下屋则子 / 神谷浩史', 'poster': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2545044503.jpg'}
{'标题': '养家之人', '得分': '8.3', '上映时间': '2017', '时长': '94分钟', '国家': '爱尔兰 加拿大 卢森堡', '导演': '诺拉·托梅', '演员': '莎拉·乔德利 / 索玛·查亚 / 诺林·古拉姆高斯', 'poster': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2544510784.jpg'}

然后将爬取到的数据保存在csv文件中:

import requests
from lxml import etree
import json
import csv

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',
    'Referer':'https://www.douban.com/'
}

url = 'https://movie.douban.com/cinema/nowplaying/chengdu/'
response = requests.get(url,headers=headers)
text = response.text
html = etree.HTML(text)
ul = html.xpath('//ul[@class="lists"]')[0]
lis = ul.xpath('./li')
f = open('电影.csv','w',encoding='utf-8')
filedname = ['标题','得分','年代','时长','产地','导演','演员']
writer = csv.DictWriter(f,fieldnames=filedname)
writer.writeheader()
for li in lis:
    title = li.xpath('@data-title')[0]
    score = li.xpath('@data-score')[0]
    data = li.xpath('@data-release')[0]
    time = li.xpath('@data-duration')[0]
    place = li.xpath('@data-region')[0]
    director = li.xpath('@data-director')[0]
    actor = li.xpath('@data-actors')[0]
    movie = {
        '标题':title,
        '得分':score,
        '年代':data,
        '时长':time,
        '产地':place,
        '导演':director,
        '演员':actor
    }
    writer.writerow(movie)
f.close()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值