import requests from lxml import etreeurl_ = "" page_source = (url=url_) print("响应结果:n",) model = etree.HTML()以上代码就是最简单的获取网页源码的方式,我们运行发现好像没有达到我们的预期结果: 出现了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_ = "" 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 = (url=url_,headers=headers_) 15 16 print("响应结果:n",) 17 18 model = etree.HTML()可以看到此时网站已经正确响应了,我们拿到了我们的“理想数据“,但仔细看了看响应的数据,然后搜索了一下,发现好像没有看到某首歌曲 的信息,也就是说目前返回的数据并不包含歌曲排行榜数据: 我明明是打开的这个 网址啊,而且用浏览器打开后也加载出音乐排行榜的歌曲了啊,为什么返回的网页源码中找不到歌曲信息呢?不知道你发现没有,当浏览器打开这个网址时,页面中间区域排行榜数据处于一个正在加载中状态,并不是一下子整个页面出来的(你网速好可以忽略了...) 就类似于上图这样,一部分页面出来了而一部分还未加载完成,这时候你是不是就想到了Ajax异步加载了?这就对了,这块数据是Ajax后期加载出来的,是有一个新请求的,直接通过代码获取网页源码肯定不会得到期望结果的,我们应该想办法知道Ajax通过什么方式请求了哪个地址以及得到了什么类型的结果,于是乎浏览器的开发者工具就派上用场了: 我们可以看到当我们打开这个页面时都进行了右侧的请求响应处理,我们响应的Ajax请求肯定就在其中了,我们可以慢慢找,不过我们知道是Ajax请求了,那我们直接过滤“XHR”: 进过过滤我们发现就这一个请求,然后看了一下Response,最后确认就是它了!! 歌曲就在其中了,于是我们确定这就是我们最终要请求的URL了,然后我们再看一下该请求的相关信息: 于是我们知道了URL是: =103&type=0&page=1&limit=100&_=1517477892257 请求方式是:GET方式 等信息,那我们就接着修改代码吧: (URL的请求参数,比如page、limit等我们就不细究了,一看就知道当前页码和每页返回数据大小)
import requests from lxml import etreeurl_ = "=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 = (url=url_,headers=headers_)print("响应结果:n",)model = etree.HTML()运行之后: 可以看到这就是我们理想数据了,相关音乐排行榜数据都在其中了,剩下的就是提取数据了,这里我们使用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
import requests from lxml import etreeurl_ = "=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 = (url=url_, headers=headers_) print("响应结果:n", ) model = etree.HTML() 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_ = "=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 = (url=url_, headers=headers_)print("响应结果:n", )model = etree.HTML() 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))
转载于:.html
本文发布于:2024-01-31 21:19:19,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170670716231425.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |