一起学爬虫——使用xpath库爬取猫眼电影国内票房榜
之前分享了一篇使用requests库爬取豆瓣电影250的文章,今天继续分享使用xpath爬取猫眼电影热播口碑榜
XPATH语法
XPATH(XML Path Language)是一门用于从XML文件中查找信息的语言。通用适用于从HTML文件中查找数据。工欲善其事必先利其器,我们首先来了解XPATH常用的语法规则。
常用匹配规则:
| 属性 | 匹配规则描述 |
|---|---|
| nodename | 匹配此节点的所有子节点 |
| / | 匹配当前节点的直接子节点,不包含孙节点 |
| // | 匹配当前节点的所有子孙节点 |
| . | 匹配当前节点 |
| .. | 匹配当前节点的父节点 |
| @ | 匹配属性值 |
XPATH的匹配功能很强大,上面6种匹配规则可以搭配使用,通过上面的6种匹配规则即可爬取到网页上所有的我们想要的数据。
使用下面的HTML文档介绍上述6种规则的搭配使用。
<html>
<div id="div_id1" class="div_class1">
<ul>
<li class="li_item1"><a href="www.bigdata17.com">Summer哥的自留地</a></li>
<li class="li_item2 li"><a href="li_test.html">test li</a></li>
</ul>
<li>20</li>
<li>30</li>
<ul>
</ul>
</div>
</html>
| 匹配表达式 | 结果 |
|---|---|
| //* | 匹配网页中所有的节点 |
| //div | 匹配所有div节点 |
| //div/li | 匹配所有div节点的所有li节点 |
| //a[@href="www.bigdata17.com"/..] | 匹配href属性为www.bigdata17.com的A节点的父节点 |
| //li[@class="li_item1"] | 匹配所有li元素,且为class属性为"li_item1" |
| //li[@class] | 匹配所有拥有class属性的li元素 |
| //li/a/@href | 获取所有li元素a子元素的href属性值,注意和//li[@class="li_item1"的且 |
| //li//text() | 过去li节点所有子节点的文本 |
| //li[@class="li_item1"]/a/text() | 获取class属性为li_item1的li节点所有a子节点的文本 |
| //li[contains(@class,"li")]/a/text() | 获取class属性值包含li的li节点所有a子节点的文本 |
| //div[contains(@class,"div") and @id="div_id1"]/ul | 获取所有class属性包含“div”且id属性值为“div_id1”的div节点的ul子节点 |
| /div/ul[li>20] | 选取div节点的所有 ul节点,且其中的li节点的值须大于20 |
| /div/ul[1] | 匹配属于div节点的第一个 ul节点。 |
| /div/ul[last()] | 匹配属于div 子节点的最后一个ul节点 |
| /div/ul[last()-1] | 匹配属于div 子节点的倒数第二个ul节点 |
| /div/ul[position() < 3] | 匹配最前面的两个属于div元素的ul子元素 |
通过上面的匹配规则,我们就可以使用XPATH来解析爬取猫眼电影国内票房榜的数据。
XPATH要配合requests一起使用,使用requests抓取网页信息,然后使用XPATH解析网页信息,XPATH在lxml库中,因此需要在pycharm中安装lxml。
1、获取取猫眼电影热播口碑榜HTML文件
下面是抓取猫眼电影热播口碑榜的代码:
from lxml import etree
import requests
url = 'http://maoyan.com/board/1'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}
response = requests.get(url,headers=headers)
html = response.text
2、提取电影名
现在浏览器的开发者工具都支持提取xpath规则,具体步骤如下:
首先在浏览器中打开网址,按下F12,ctrl+f查找电影名,鼠标右键弹出的菜单,点击Copy选项,点击Copy Xpath。到此就可以把电影名称的xpath匹配规则提取出来:

电影名称提取的规则是:
//*[@id="app"]/div/div/div/dl/dd[1]/div/div/div[1]/p[1]/a
我们使用这个规则看下是否能提取出电影名称,代码如下:
from lxml import etree
import requests
url = 'http://maoyan.com/board/7'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}
response = requests.get(url,headers=headers)
html = response.text
movie_name_xpath = '//*[@id="app"]/div/div/div/dl/dd[1]/div/div/div[1]/p[1]/a/text()'
s = etree.HTML(html)
movie_name = s.xpath(movie_name_xpath)
print(movie_name)
运行结果:[<Element a at 0x35f5248>]
上面的结果显示抓取到的是a元素,就是html中的a标签,要想获取该元素中的文本值,必须在xpath匹配规则追加/text(),下面是追加/text()后的代码及运行结果:
from lxml import etree
import requests
url = 'http://maoyan.com/board/1'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}
response = requests.get(url,headers=headers)
html = response.text
movie_name_xpath = '//*[@id="app"]/div/div/div/dl/dd[1]/div/div/div[1]/p[1]/a/text()'
s = etree.HTML(html)
movie_name = s.xpath(movie_name_xpath)
print(movie_name)
运行结果['嗝嗝老师']
这里只是提取一部电影的名称,我们要想提取当前网页的所有电影的名称,匹配规则怎么写呢?
下面是当前页10部电影的xpath匹配规则
//*[@id="app"]/div/div/div/dl/dd[1]/div/div/div[1]/p[1]/a
//*[@id="app"]/div/div/div/dl/dd[2]/div/div/div[1]/p[1]/a
//*[@id="app"]/div/div/div/dl/dd[3]/div/div/div[1]/p[1]/a
//*[@id="app"]/div/div/div/dl/dd[4]/div/div/div[1]/p[1]/a
//*[@id="app"]/div/div/div/dl/dd[5]/div/div/div[1]/p[1]/a
//*[@id="app"]/div/div/div/dl/dd[6]/div/div/div[1]/p[1]/a
//*[@id="app"]/div/div/div/dl/dd[7]/div/div/div[1]/p[1]/a
//*[@id="app"]/div/div/div/dl/dd[8]/div/div/div[1]/p[1]/a
//*[@id="app"]/div/div/div/dl/dd[9]/div/div/div[1]/p[1]/a
//*[@id="app"]/div/div/div/dl/dd[10]/div/div/div[1]/p[1]/a
发现dd的数字会变化,其他的都不变,因此用通配符“*”代替dd节点中的数字,提取当前页所有电影名字的xpath规则为:
//*[@id="app"]/div/div/div/dl/dd[*]/div/div/div[1]/p[1]/a
看下最后的运行结果是什么。
from lxml import etree
import requests
url = 'http://maoyan.com/board/1'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}
response = requests.get(url,headers=headers)
html = response.text
movie_name_xpath = '//*[@id="app"]/div/div/div/dl/dd[*]/div/div/div[1]/p[1]/a/text()'
s = etree.HTML(html)
movie_name = s.xpath(movie_name_xpath)
print(movie_name)
运行结果:['嗝嗝老师', '毒液:致命守护者', '无名之辈', '恐龙王', '流浪猫鲍勃', '无双', '名侦探柯南:零的执行人', '飓风奇劫', '影', '你好,之华']
可见使用通配符*把所有的电影名称都提取出来了。
3、提取电影图片链接
通过上步骤获取图片的xpath匹配规则为:
//*[@id="app"]/div/div/div/dl/dd[1]/a/img[2]
通过开发者工具知道img节点有三个属性,分别是alt,class和src。

其中src的是图片的地址,在xpath提取规则追加上@src,变为:
//*[@id="app"]/div/div/div/dl/dd[1]/a/img[2]/@src
看下这个xpath规则是否能提取到图片的链接地址:
from lxml import etree
import requests
url = 'http://maoyan.com/board/7'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}
response = requests.get(url,headers=headers)
html = response.text
movie_img_xpath = '//*[@id="app"]/div/div/div/dl/dd[1]/a/img[2]/@src'
s = etree.HTML(html)
movie_img = s.xpath(movie_img_xpath)
print(movie_img)
运行的结果是:[]
怎么会得不到src属性的值呢?难道src属性不存在?
通过鼠标右键查看网页源文件:

原来src变成了data-src。修改xpath规则后看下能否提取出电影图片链接:
from lxml import etree
import requests
url = 'http://maoyan.com/board/7'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}
response = requests.get(url,headers=headers)
html = response.text
movie_img_xpath = '//*[@id="app"]/div/div/div/dl/dd[1]/a/img[2]/@data-src'
s = etree.HTML(html)
movie_img = s.xpath(movie_img_xpath)
print(movie_img)
运行结果:
['http://p0.meituan.net/movie/36f1a50b4eae6aa93e3f7a373fb6ee89991083.jpg@160w_220h_1e_1c']
电影图片链接提取成功。
这是提取一部电影的xpath规则,下面是当前页面10部电影图片的规则:
//*[@id="app"]/div/div/div/dl/dd[1]/a/img[2]/@data-src
//*[@id="app"]/div/div/div/dl/dd[2]/a/img[2]/@data-src
//*[@id="app"]/div/div/div/dl/dd[3]/a/img[2]/@data-src
...
...
...
//*[@id="app"]/div/div/div/dl/dd[9]/a/img[2]/@data-src
//*[@id="app"]/div/div/div/dl/dd[10]/a/img[2]/@data-src
观察发现dd的数字会变化,其他的都不变,因此用通配符“*”代替dd节点中的数字,提取当前页所有电影图片链接的xpath规则为:
//*[@id="app"]/div/div/div/dl/dd[*]/a/img[2]/@data-src
以此类推,通过上面的方式提取出当前页所有电影名称,图片地址,主演,上映时间,评分的xpath匹配规则:
movie_name_xpath = '//*[@id="app"]/div/div/div/dl/dd[*]/div/div/div[1]/p[1]/a/text()'
movie_img_xpath = '//*[@id="app"]/div/div/div/dl/dd[*]/a/img[2]/@data-src'
movie_actor_xpath = '//*[@id="app"]/div/div/div/dl/dd[*]/div/div/div[1]/p[2]/text()'
movie_release_time_xpath = '//*[@id="app"]/div/div/div/dl/dd[*]/div/div/div[1]/p[3]/text()'
movie_score_xpath =
'//*[@id="app"]/div/div/div/dl/dd[*]/div/div/div[2]/p/i/text()'
爬取猫眼电影国内热播榜的完整代码如下:
# coding:utf-8
from lxml import etree
import requests
#获取网页
def getHtml(url):
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}
response = requests.get(url,headers=headers)
html = response.text
return html
#
# movie_img_xpath = '//*[@id="app"]/div/div/div/dl/dd[1]/div/div/div[2]/p/i/text()'
# s = etree.HTML(html)
# movie_img = s.xpath(movie_img_xpath)
# print(movie_img)
#解析网页
def parseHtml(html):
s = etree.HTML(html)
movie_name_xpath = '//*[@id="app"]/div/div/div/dl/dd[*]/div/div/div[1]/p[1]/a/text()'
movie_img_xpath = '//*[@id="app"]/div/div/div/dl/dd[*]/a/img[2]/@data-src'
movie_actor_xpath = '//*[@id="app"]/div/div/div/dl/dd[*]/div/div/div[1]/p[2]/text()'
movie_release_time_xpath = '//*[@id="app"]/div/div/div/dl/dd[*]/div/div/div[1]/p[3]/text()'
movie_score_xpath = '//*[@id="app"]/div/div/div/dl/dd[*]/div/div/div[2]/p/i/text()'
movie_name = s.xpath(movie_name_xpath)
movie_img = s.xpath(movie_img_xpath)
movie_actor = s.xpath(movie_actor_xpath)
movie_score = s.xpath(movie_score_xpath)
movie_release_time = s.xpath(movie_release_time_xpath)
for i in range(len(movie_name)):
print('电影名称:' + movie_name[i])
print('主演:' + movie_actor[i].strip())
print('图片链接:' + movie_img[i].strip())
print('评分:' + movie_score[2*i] + movie_score[2*i + 1])
print(movie_release_time[i])
print('-------------------------------------------强力分割线-------------------------------------------')
def main():
url = 'http://maoyan.com/board/7'
html = getHtml(url)
parseHtml(html)
if __name__ == '__main__':
main()
总结:
在使用开发者工具提取xpath规则获取不到相应的数据时,要注意xpath规则是否准确,有些浏览器会加上一些多余的标签,或者将节点的属性名改掉,例如上面例子中将的img节点的src属性变为data-src。结合查看源文件都可以获取到正确的xpath规则。
一起学爬虫——使用xpath库爬取猫眼电影国内票房榜的更多相关文章
- # 爬虫连载系列(1)--爬取猫眼电影Top100
前言 学习python有一段时间了,之前一直忙于学习数据分析,耽搁了原本计划的博客更新.趁着这段空闲时间,打算开始更新一个爬虫系列.内容大致包括:使用正则表达式.xpath.BeautifulSoup ...
- # [爬虫Demo] pyquery+csv爬取猫眼电影top100
目录 [爬虫Demo] pyquery+csv爬取猫眼电影top100 站点分析 代码君 [爬虫Demo] pyquery+csv爬取猫眼电影top100 站点分析 https://maoyan.co ...
- 用requests库爬取猫眼电影Top100
这里需要注意一下,在爬取猫眼电影Top100时,网站设置了反爬虫机制,因此需要在requests库的get方法中添加headers,伪装成浏览器进行爬取 import requests from re ...
- python学习(23)requests库爬取猫眼电影排行信息
本文介绍如何结合前面讲解的基本知识,采用requests,正则表达式,cookies结合起来,做一次实战,抓取猫眼电影排名信息. 用requests写一个基本的爬虫 排行信息大致如下图 网址链接为ht ...
- requests库爬取猫眼电影“最受期待榜”榜单 --网络爬虫
目标站点:https://maoyan.com/board/6 # coding:utf8 import requests, re, json from requests.exceptions imp ...
- 利用Python3的requests和re库爬取猫眼电影笔记
以下笔记,作为参考借鉴,如有疑问可以联系我进行交流探讨! 代码思路很简单,简单概括为: 首先利用requests的get方法获取页面的html文件,之后对得到的html文件进行相对应的正则处理,然 ...
- 爬虫练习之正则表达式爬取猫眼电影Top100
#猫眼电影Top100import requests,re,timedef get_one_page(url): headers={ 'User-Agent':'Mozilla/5.0 (Window ...
- 爬虫基本库request使用—爬取猫眼电影信息
使用request库和正则表达式爬取猫眼电影信息. 1.爬取目标 猫眼电影TOP100的电影名称,时间,评分,等信息,将结果以文件存储. 2.准备工作 安装request库. 3.代码实现 impor ...
- PYTHON 爬虫笔记八:利用Requests+正则表达式爬取猫眼电影top100(实战项目一)
利用Requests+正则表达式爬取猫眼电影top100 目标站点分析 流程框架 爬虫实战 使用requests库获取top100首页: import requests def get_one_pag ...
随机推荐
- TortoiseGit安装、配置
1 TortoiseGit简介 tortoiseGit是一个开放的git版本控制系统的源客户端,支持Winxp/vista/win7.该软件功能和git一样 不同的是:git是命令行操作模式,tort ...
- P2495 [SDOI2011]消耗战 lca倍增+虚树+树形dp
题目:给出n个点的树 q次询问 问切断 k个点(不和1号点联通)的最小代价是多少 思路:树形dp sum[i]表示切断i的子树中需要切断的点的最小代价是多少 mi[i]表示1--i中的最小边权 ...
- docker_监控
目录 Docker 自带的监控子命令 sysdig Weave Scope cAdvisor Prometheus Prometheus 的架构 多维数据模型 Docker 自带的监控子命令 ps d ...
- java替换ascii表字符
如下: //处理特殊字符 public String dealSpecialXml(String xml){ String result = ""; //result = xml. ...
- makefile :=和+=
经常有人分不清= .:=和+=的区别 这里我总结下做下详细的分析: 首先你得清楚makefile的运行环境,因为我是linux系统,那么我得运行环境是shell 在Linux的shell里,shel ...
- server被强制关闭,
一个client和一个Server,两者之间建立了一个基于TCP的socket连接,在刚刚建立好连接后,尚未进行数据传输,Server端应用程序突然crush掉了,现在立刻重启Server端应用程序( ...
- CMDB服务器管理系统【s5day89】:部分数据表结构-资产入库思路
1.用django的app作为统一调用库的好处 1.创建repository app截图如下: 2.好处如下: 1.app的本质就是一个文件夹 2.以后所有的app调用数据就只去repository调 ...
- 深入学习javaScript闭包(闭包的原理,闭包的作用,闭包与内存管理)
前言 虽然JavaScript是一门完整的面向对象的编程语言,但这门语言同时也拥有许多函数式语言的特性. 函数式语言的鼻祖是LISP,JavaScript在设计之初参考了LISP两大方言之一的Sche ...
- Codeforces Round #527 (Div. 3) . F Tree with Maximum Cost
题目链接 题意:给你一棵树,让你找一个顶点iii,使得这个点的∑dis(i,j)∗a[j]\sum dis(i,j)*a[j]∑dis(i,j)∗a[j]最大.dis(i,j)dis(i,j)dis( ...
- java核心36
1 Java平台 Java采用的是解释和编译混合的模式.它首先通过javac将源码编译成字节码文件class.然后在运行的时候通过解释器或者JIT将字节码转换成最终的机器码.只是用解释器的缺点:抛弃了 ...