之前分享了一篇使用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. # 爬虫连载系列(1)--爬取猫眼电影Top100

    前言 学习python有一段时间了,之前一直忙于学习数据分析,耽搁了原本计划的博客更新.趁着这段空闲时间,打算开始更新一个爬虫系列.内容大致包括:使用正则表达式.xpath.BeautifulSoup ...

  2. # [爬虫Demo] pyquery+csv爬取猫眼电影top100

    目录 [爬虫Demo] pyquery+csv爬取猫眼电影top100 站点分析 代码君 [爬虫Demo] pyquery+csv爬取猫眼电影top100 站点分析 https://maoyan.co ...

  3. 用requests库爬取猫眼电影Top100

    这里需要注意一下,在爬取猫眼电影Top100时,网站设置了反爬虫机制,因此需要在requests库的get方法中添加headers,伪装成浏览器进行爬取 import requests from re ...

  4. python学习(23)requests库爬取猫眼电影排行信息

    本文介绍如何结合前面讲解的基本知识,采用requests,正则表达式,cookies结合起来,做一次实战,抓取猫眼电影排名信息. 用requests写一个基本的爬虫 排行信息大致如下图 网址链接为ht ...

  5. requests库爬取猫眼电影“最受期待榜”榜单 --网络爬虫

    目标站点:https://maoyan.com/board/6 # coding:utf8 import requests, re, json from requests.exceptions imp ...

  6. 利用Python3的requests和re库爬取猫眼电影笔记

    以下笔记,作为参考借鉴,如有疑问可以联系我进行交流探讨! 代码思路很简单,简单概括为:   首先利用requests的get方法获取页面的html文件,之后对得到的html文件进行相对应的正则处理,然 ...

  7. 爬虫练习之正则表达式爬取猫眼电影Top100

    #猫眼电影Top100import requests,re,timedef get_one_page(url): headers={ 'User-Agent':'Mozilla/5.0 (Window ...

  8. 爬虫基本库request使用—爬取猫眼电影信息

    使用request库和正则表达式爬取猫眼电影信息. 1.爬取目标 猫眼电影TOP100的电影名称,时间,评分,等信息,将结果以文件存储. 2.准备工作 安装request库. 3.代码实现 impor ...

  9. PYTHON 爬虫笔记八:利用Requests+正则表达式爬取猫眼电影top100(实战项目一)

    利用Requests+正则表达式爬取猫眼电影top100 目标站点分析 流程框架 爬虫实战 使用requests库获取top100首页: import requests def get_one_pag ...

随机推荐

  1. Announcing Microsoft Research Open Data – Datasets by Microsoft Research now available in the cloud

    The Microsoft Research Outreach team has worked extensively with the external research community to ...

  2. 在Django中使用ORM创建图书管理系统

    一.ORM(对象关系映射) 很多语言的web框架中都有这个概念 1. 为什么要有ORM? 1. 写程序离不开数据,要使用数据就需要连接数据库,但是不同的数据库在sql语句上(mysql,oracle等 ...

  3. Linux saltstack常用模块

    所有模块 salt '172.30.100.126' sys.list_modules #列出当前版本支持的模块 salt '*' sys.doc cp #显示指定模块的文档 archive模块 实现 ...

  4. BSGS与扩展BSGS

    BSGS \(BSGS\)算法又称大步小步\((Baby-Step-Giant-Step)\)算法 \(BSGS\)算法主要用于解以下同余方程 \[A^x\equiv B(mod\ p)\]其中\(( ...

  5. MySQL 无法启动,出现 “发生系统错误 1067。”

    出现场景 使用 net start mysql 时无法启动,并出现:发生系统错误 1067. 解决过程 很多情况都可以导致该错误提示,可以先查找 "Windows 日志" : 打开 ...

  6. Docker:dockerfile构建php项目 [八]

    一.把项目封装成docker镜像的步骤 把项目封装成docker镜像的步骤: 1.先运行一个基础容器,手动制作docker镜像 2.编写dockerfile,构建镜像 3.测试运行 二.dockerf ...

  7. c# mvc 在控制器中动态解析cshtml文件并获取对应的html代码

    public static string GetViewHtml(ControllerContext context, string viewName, Object param) { if (str ...

  8. C#基于任务的异步模式

    using System; using System.Threading; using System.Threading.Tasks; using static System.Console; //异 ...

  9. Linux配置日志服务器

    title: Linux配置日志服务器 tags: linux, 日志服务器 --- Linux配置日志服务器 日志服务器配置文件:/etc/rsyslog.conf 服务器端: 服务器IP如下: 编 ...

  10. Mysql中设置指定IP的特定用户及特定权限

    创建用户:格式:grant select on 数据库.* to 用户名@登录主机 identified by '密码' 举例: 例 1:增加一个用户 test1 密码为 abc,让他可以在任何主机上 ...