【个人】爬虫实践,利用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

相关文章

Python实现终端清屏的几种方式详解

《Python实现终端清屏的几种方式详解》在使用Python进行终端交互式编程时,我们经常需要清空当前终端屏幕的内容,本文为大家整理了几种常见的实现方法,有需要的小伙伴可以参考下... 目录方法一:使用 `os` 模块调用系统命令方法二:使用 `subprocess` 模块执行命令方法三:打印多个换行符模拟

虚拟机Centos7安装MySQL数据库实践

《虚拟机Centos7安装MySQL数据库实践》用户分享在虚拟机安装MySQL的全过程及常见问题解决方案,包括处理GPG密钥、修改密码策略、配置远程访问权限及防火墙设置,最终通过关闭防火墙和停止Net... 目录安装mysql数据库下载wget命令下载MySQL安装包安装MySQL安装MySQL服务安装完成

RabbitMQ消息总线方式刷新配置服务全过程

《RabbitMQ消息总线方式刷新配置服务全过程》SpringCloudBus通过消息总线与MQ实现微服务配置统一刷新,结合GitWebhooks自动触发更新,避免手动重启,提升效率与可靠性,适用于配... 目录前言介绍环境准备代码示例测试验证总结前言介绍在微服务架构中,为了更方便的向微服务实例广播消息,

SpringBoot整合(ES)ElasticSearch7.8实践

《SpringBoot整合(ES)ElasticSearch7.8实践》本文详细介绍了SpringBoot整合ElasticSearch7.8的教程,涵盖依赖添加、客户端初始化、索引创建与获取、批量插... 目录SpringBoot整合ElasticSearch7.8添加依赖初始化创建SpringBoot项

Zabbix在MySQL性能监控方面的运用及最佳实践记录

《Zabbix在MySQL性能监控方面的运用及最佳实践记录》Zabbix通过自定义脚本和内置模板监控MySQL核心指标(连接、查询、资源、复制),支持自动发现多实例及告警通知,结合可视化仪表盘,可有效... 目录一、核心监控指标及配置1. 关键监控指标示例2. 配置方法二、自动发现与多实例管理1. 实践步骤

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

MySQL 迁移至 Doris 最佳实践方案(最新整理)

《MySQL迁移至Doris最佳实践方案(最新整理)》本文将深入剖析三种经过实践验证的MySQL迁移至Doris的最佳方案,涵盖全量迁移、增量同步、混合迁移以及基于CDC(ChangeData... 目录一、China编程JDBC Catalog 联邦查询方案(适合跨库实时查询)1. 方案概述2. 环境要求3.

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.