【个人】爬虫实践,利用xpath方式爬取数据之爬取虾米音乐排行榜

本文主要是介绍【个人】爬虫实践,利用xpath方式爬取数据之爬取虾米音乐排行榜,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

实验网站:虾米音乐排行榜
网站地址: http://www.xiami.com/chart 
难度系数:★☆☆☆☆
依赖库:request、lxml的etree (安装lxml:pip install lxml)
IDEA开发工具:PyCharm_2017.3
Python版本:Python3
期望结果:爬取出排行版歌名以及对应歌手

运行效果图:
音乐排行榜:
爬取数据结果图:

像这种简单的爬取就没必要使用Scrapy框架进行处理,是在有点大材小用,不过如果你刚开始学Scrapy的话,拿这些简单的练手是必须的,从简单的开始,慢慢去熟悉、掌握Scrapy框架。用BeautifulSoup也可以,简单实用,尤其元素选择器方面和Jquery很类似,上手比较快,但是最近我还是感觉XPath比较好用,所以今天就用XPath方式对数据进行提取吧。不过为了分享更多内容,让初学者少踩坑,快进步,我打算把这个实验再用Scrapy实现一遍,对于老鸟来说这实在没多大意义,但是对于初学者来说却能更好的理清思路,少走弯路。
这篇入门教程和未来Scrapy爬取虾米音乐排行榜的教程我都会以最简单直白的方式进行说明,基本从第一句代码开始写起,期间对遇到的问题进行分析、解决、对代码逐步完善,同时辅之更清晰明了的截图,让各位初学者更直观的看到代码逐步完善的过程,更好的理清思路。
首先用浏览器(推荐Chrome内核的浏览器,例如谷歌Chrome浏览器,Cent百分浏览器,此处用的Cent浏览器,感觉比Chrome更好用)打开网站  http://www.xiami.com/chart  ,基本就是我们看到的这样:
我们此时先试着写简单的代码,我们一步一步处理,遇到问题去解决:
import requests
from lxml import etreeurl_ = "http://www.xiami.com/chart"
page_source = requests.get(url=url_)
print("响应结果:\n",page_source.text)
model = etree.HTML(page_source.text)
以上代码就是最简单的获取网页源码的方式,我们运行发现好像没有达到我们的预期结果:
出现了400错误,什么问题呢?下面蓝色区域画出来的部分已经很明确的说明了,因为我们浏览器发送的请求服务端无法识别,仔细一想浏览器打开这个网址正常,而我们通过代码则不行,很明显就是Use-Agent(UA)不匹配了,找到问题原因就好办了,我们可以模拟一个UA,例如:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87,接着我们修改一下代码:
 1 import requests
 2 
 3 from lxml import etree
 4 
 5 
 6 url_ = "http://www.xiami.com/chart"
 7 
 8 headers_ = {
 9 
10     'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87'
11 
12 }
13 
14 page_source = requests.get(url=url_,headers=headers_)
15 
16 print("响应结果:\n",page_source.text)
17 
18 model = etree.HTML(page_source.text)
可以看到此时网站已经正确响应了,我们拿到了我们的“理想数据“,但仔细看了看响应的数据,然后搜索了一下,发现好像没有看到某首歌曲
的信息,也就是说目前返回的数据并不包含歌曲排行榜数据:
我明明是打开的这个  http://www.xiami.com/chart 网址啊,而且用浏览器打开后也加载出音乐排行榜的歌曲了啊,为什么返回的网页源码中找不到歌曲信息呢?不知道你发现没有,当浏览器打开这个网址时,页面中间区域排行榜数据处于一个正在加载中状态,并不是一下子整个页面出来的(你网速好可以忽略了...)
就类似于上图这样,一部分页面出来了而一部分还未加载完成,这时候你是不是就想到了Ajax异步加载了?这就对了,这块数据是Ajax后期加载出来的,是有一个新请求的,直接通过代码获取网页源码肯定不会得到期望结果的,我们应该想办法知道Ajax通过什么方式请求了哪个地址以及得到了什么类型的结果,于是乎浏览器的开发者工具就派上用场了:
我们可以看到当我们打开这个页面时都进行了右侧的请求响应处理,我们响应的Ajax请求肯定就在其中了,我们可以慢慢找,不过我们知道是Ajax请求了,那我们直接过滤“XHR”:
进过过滤我们发现就这一个请求,然后看了一下Response,最后确认就是它了!!
歌曲就在其中了,于是我们确定这就是我们最终要请求的URL了,然后我们再看一下该请求的相关信息:
于是我们知道了URL是: http://www.xiami.com/chart/data?c=103&type=0&page=1&limit=100&_=1517477892257  请求方式是:GET方式 等信息,那我们就接着修改代码吧:
(URL的请求参数,比如page、limit等我们就不细究了,一看就知道当前页码和每页返回数据大小)
import requests
from lxml import etreeurl_ = "http://www.xiami.com/chart/data?c=103&type=0&page=1&limit=100&_=1517477892257"headers_ = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87'}
page_source = requests.get(url=url_,headers=headers_)print("响应结果:\n",page_source.text)model = etree.HTML(page_source.text)
运行之后:
可以看到这就是我们理想数据了,相关音乐排行榜数据都在其中了,剩下的就是提取数据了,这里我们使用XPath语法提取,首先还是在浏览器那边定位一下我们想要的歌曲名、歌手所在元素位置,然后确定XPath路径写法。
我们看到歌曲名在<a>标签里面,而且这个标签是在样式类型为“info”的div标签里面嵌套的,层次为:
<div class="info"><p><strong><a>歌曲名等信息  在第一个p标签里面</a></strong></p><p>......</p>
</div>
那我们根据这个层级初步写出一个XPath路径:
//div[@class="info"]/p[1]/strong/a/text()    
我们使用XPath Helper插件进行验证一下:
    我们发现这句XPath选择是可以把当前页面所有的歌曲名称选择出来的,然后就是再选择歌曲对应的歌手,我们再看一下歌手标签所在的DOM结构:
我们看到歌曲名在<a>标签里面,而且这个标签是在样式类型为“info”的div标签里面嵌套的,层次为:
<div class="info"><p>......</p><p><a>歌手名称,在第二个p标签里面</a></p>
基于以上结构,我们初步下一个XPath路径:
//div[@class="info"]/p[2]/a
我们使用XPath Helper插件进行验证一下:
此时我们发现这个XPath选择确实把歌手名称选中了,但是好像有个问题,明明查询出来100首歌曲,怎么却有129位歌手呢?对应不起来啊。别急,那我们就仔细看一下每一首歌曲的歌手吧
从中发现,一首歌曲可能有多位演唱者,每一位演唱者占用一个<a>标签,且用“;”分隔,如下:
这样的话我们改进一下XPath选择,试试选择<a>标签所在的p标签,这样把多位歌手(即多个a标签)看成一个list集合,我们在Python代码处理即可,修改后的XPath选择如下:
//div[@class='info']/p[2]
此时我们看到这次选择的就不是每一位歌手所在a标签了,二是上一级的整个p标签,而且选择出来的歌手一共100位,正好和歌曲个数对应起来了,那么就到此为止,我们用代码处理:
import requests
from lxml import etreeurl_ = "http://www.xiami.com/chart/data?c=103&type=0&page=1&limit=100&_=1517477892257"headers_ = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87'
}page_source = requests.get(url=url_, headers=headers_)
print("响应结果:\n", page_source.text)
model = etree.HTML(page_source.text)
songs_list = model.xpath('//div[@class="info"]/p[1]/strong/a/text()')songer = model.xpath("//div[@class='info']/p[2]")
print("歌曲个数:{}   歌手个数:{}".format(len(songs_list),len(songer)))

 


运行结果:
对代码继续进行处理完善:
import requests
from lxml import etree
url_ = "http://www.xiami.com/chart/data?c=103&type=0&page=1&limit=100&_=1517477892257"headers_ = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87'
}
page_source = requests.get(url=url_, headers=headers_)print("响应结果:\n", page_source.text)model = etree.HTML(page_source.text)
songs_list = model.xpath('//div[@class="info"]/p[1]/strong/a/text()')
songer = model.xpath("//div[@class='info']/p[2]")
print("歌曲个数:{}   歌手个数:{}".format(len(songs_list), len(songer)))
for index, item in enumerate(songs_list):# 继续处理一首歌曲有多位演唱者的情况,因为每一位演唱者都在一个a标签里面,我们把多个a标签看成一个list集合处理songer_list = songer[index].xpath(".//a/text()")# 每一首歌曲的每一位演唱者组成一个list集合,我们利用join方法对list集合的每一项进行拼接,组成一个字符串结果dealed_songer = ",".join(songer_list)# 最后按格式输出结果print("{}、{}\t【{}】".format(index + 1, item, dealed_songer))

 


最终结果:
歌曲个数:100   歌手个数:100
1、Bad Boy    【Red Velvet(레드벨벳)】
2、Electric Kiss    【EXO(엑소)】
3、Cosmic Railway    【EXO(엑소)】
4、说散就散    【袁娅维(Tia)】
5、追光者    【岑宁儿】
6、我们不一样    【大壮】
7、带你去旅行    【校长(张驰)】
8、刚好遇见你    【李玉刚】
9、123我爱你    【新乐尘符】
10、空空如也    【胡66】
11、成都    【赵雷(雷子)】
12、红昭愿    【音阙诗听(Interseting)】
13、等你下课    【周杰伦,杨瑞代】
14、9420    【麦小兜】
15、Ei Ei    【偶像练习生】
16、广东爱情故事    【广东雨神】
17、小幸运    【田馥甄】
18、九张机    【叶炫清】
19、岁月神偷    【金玟岐】
20、BINGBIAN病变 (女声版)    【鞠文娴】
21、你就不要想起我    【田馥甄(Hebe)】
22、最美情侣    【白小白】
23、全部都是你    【Dragon Pig,Cloud Wang】
24、告白气球    【周杰伦(Jay Chou)】
25、사랑을 했다    【iKON(TEAM B)】
26、过往    【邹施如】
27、文爱    【CG(CHIGGA GANG黄鬼帮)】
28、差一步    【大壮】
29、在人间    【王建房】
30、Panama    【Matteo】
31、没有你陪伴真的好孤单    【梦然】
32、童话镇    【陈一发儿(陈一发)】
33、尽头    【音阙诗听(Interseting)】
34、Lovin’ You Mo’    【EXO(엑소)】
35、勉为其难    【王冕】
36、最美的期待    【周笔畅(BiBi Chou)】
37、非酋    【薛明媛,朱贺】
38、平凡之路    【朴树】
39、多幸运    【韩安旭】
40、再也没有    【Ryan.B,AY杨佬叁】
41、说散就散    【冯提莫(Ti mo Feng)】
42、空空如也    【任然】
43、Faded    【Alan Walker,Iselin Solheim】
44、你曾是少年    【S.H.E(SHE)】
45、小半    【陈粒(粒粒)】
46、All Right    【Red Velvet(레드벨벳)】
47、春风吹    【阿冷】
48、Shape of You    【Ed Sheeran(艾德·希兰)】
49、默    【那英】
50、喜欢你    【G.E.M.邓紫棋(邓紫棋)】
51、盗心贼    【黑龙】
52、演员 (Live)    【薛之谦】
53、恋人心    【魏新雨】
54、Please Don't Go    【Joel Adams】
55、其实都没有    【杨宗纬(Aska Yang)】
56、过客    【阿涵(周思涵)】
57、我们    【杨清柠,王乐乐】
58、丑八怪 (Live)    【薛之谦】
59、最久的瞬间    【炎亚纶(Aaron)】
60、大鱼    【周深(卡布叻)】
61、Time    【MKJ】
62、回忆总想哭    【南宫嘉骏,姜玉阳】
63、Despacito (Remix)    【Luis Fonsi,Daddy Yankee,Justin Bieber】
64、山丘    【李宗盛(Jonathan Lee)】
65、回忆那么伤    【孙子涵(Niko)】
66、后来的我们    【五月天(Mayday)】
67、一笑倾城    【汪苏泷】
68、陪你度过漫长岁月    【陈奕迅(Eason Chan)】
69、林中鸟    【葛林】
70、半壶纱    【刘珂矣】
71、生活不止眼前的苟且    【许巍】
72、给我一个理由忘记    【A-Lin(黄丽玲)】
73、光年之外    【G.E.M.邓紫棋(邓紫棋)】
74、Dream It Possible    【Delacey】
75、Sugar    【Maroon 5(魔力红)】
76、Havana    【Camila Cabello,Young Thug】
77、如果我们不曾相遇    【五月天(Mayday)】
78、全世界谁倾听你    【林宥嘉(Yoga Lin)】
79、短发    【LAMPHO(lampho猴子)】
80、退    【蒋蒋(蒋家驹)】
81、小公主    【蒋蒋,杨清柠】
82、奇妙能力歌    【陈粒(粒粒)】
83、雨后人去楼也空    【王乐乐】
84、歌在飞    【苏勒亚其其格(格格)】
85、我要你    【任素汐】
86、后会无期    【G.E.M.邓紫棋(邓紫棋)】
87、Зая    【Бамбинтон】
88、微微一笑很倾城    【杨洋】
89、Psycho (Pt. 2)    【Russ】
90、闪光 (Shinin’)    【钟铉(종현)】
91、四年半    【杨清柠】
92、情话微甜    【王圣锋,李朝】
93、愿得一人心    【李行亮】
94、病变remix    【前男友】
95、爱的就是你    【十二星宿风之少年,刘佳】
96、Grandpa    【阿克江LilAkin,Bohan Phoenix,Lofimaker】
97、好好 (想把你写成一首歌)    【五月天(Mayday)】
98、无问西东    【王菲(Faye Wong)】
99、理想三旬    【陈鸿宇】
100、走在冷风中    【刘思涵(Koala)】

    至此,本教程结束,通过本教程,你清晰的看到了这个简单数据爬取是怎么一步一步完成的,见证了从需求明确、问题原因分析、问题解决、代码完善、最终完成的整个生命周期,那么此时你也就对爬虫编写基本思路有了一个简单的认识,爬取数据的代码都不会太复杂,复杂就复杂在发现问题、解决问题方式的寻找中,好的爬虫在于数据价值、涵盖范围以及相关算法确定中。当然了,本教程爬取的数据没多大价值,仅仅是抛砖引玉而已,希望各位灵活运用。

 

转载于:https://www.cnblogs.com/geekworld/p/8410751.html

这篇关于【个人】爬虫实践,利用xpath方式爬取数据之爬取虾米音乐排行榜的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/551450

相关文章

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

gradle第三方Jar包依赖统一管理方式

《gradle第三方Jar包依赖统一管理方式》:本文主要介绍gradle第三方Jar包依赖统一管理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景实现1.顶层模块build.gradle添加依赖管理插件2.顶层模块build.gradle添加所有管理依赖包

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Linux之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll