教你用Python爬取由JavaScript产生的动态网页(以英雄联盟所有英雄的皮肤海报为例)

常规开头:有一段时间没有写博客了,今天终于有时间来写一篇关于Python爬虫的博客。刚接触Python,我也是边学边写,如若有不对的地方也请大牛在下方留言赐教。来自神秘的作者的温馨提示:此篇文章适合一些有爬虫基础的人哦,不过没有基础也没关系,那就可能要多花点时间。

那就废话不多说开始吧!

先说说什么是动态网页,动态网页就是它有一部分内容是由一些脚本语言产生的,不是直接在HTML文件里的。常用的脚本语言有JavaScript,PHP等。

IDE:PyCharm Cummunity

浏览器:Chrome

爬取目标:英雄联盟皮肤海报


目标地址:http://lol.qq.com/

主要用到的第三方库: requests:用于发起网络请求,re:正则表达式

先说思路:首先想要爬取一个网站的内容,要看一下这个网站的robots协议。在主页网址后面加/robots.txt


扫描二维码关注公众号,回复: 1464202 查看本文章

可以看到Disallow:后面为空,说明可以爬去这个网站的所有内容。

我们要爬取的是所有英雄的皮肤海报,所以第一步应该获取所有英雄的信息,所有英雄的信息在主页->游戏资料->资料库


点开后是


这里有英雄联盟所有现有的英雄,点开英雄的头像我们就可看到英雄的资料和皮肤海报。所以这个是我们爬去的第一目标,获取所有英雄资料面的地址。记录这个网址"http://lol.qq.com/web201310/info-heros.shtml",然后鼠标放在英雄图片上右键->检查


就可以看到 这些英雄头像是一个列表a href后面就是这个英雄头像对应的网址,也就是这个英雄所对应资料页面的网址。


我们的第1步就是爬出这个网址先在终端中爬取这个页面

import requests
from bs4 import BeautifulSoup
r = requests.get('http://lol.qq.com/web201310/info-heros.shtml')
r.encoding='gb2312'
soup = BeautifulSoup(r.text,'lxml')
soup

可以看到结果中没有直接有这个英雄的页面的链接但有个用来生成这个英雄列表的JavaScript的函数,说明这个列表是由JS动态生成的。接下来我们去观察英雄页面的地址



发现地址是:"http://lol.qq.com/web201310/info-defail.shtml?id=英雄名字"的格式,到这里就应该明白,我们只要获取所有英雄的名字,就可得到所有英雄的资料页面

再看获取到的数据最后面有

访问这个链接"http://lol.qq.com/biz/hero/champion.js"发现这个champion.js里刚好有着我们想要的所有的英雄名字


截取一行


前面的是这个英雄的id后面的是这个英雄的名字,我们可以用正则表达式把它们从champion.js中提取出来

def grab_hero_info():
    url1='http://lol.qq.com/biz/hero/champion.js'
    response = requests.get(url1)#拿到champion.js
    pat = re.compile(r'"([0-9]{1,4})":"([\w]*)",*')#正则表达式
    l = pat.findall(response.text)#找出champion.js中所有符合正则表达式的内容,存在一个元祖tuple l中
    return l 

这样我们就有了所有英雄的id,和名字

第二步:去英雄页面查看皮肤海报的链接的格式




发现两张不同的皮肤海报的链接格式为:"http://ossweb-img.qq.com/images/lol/web201310/skin/big皮肤号码.jpg"

的不同之处就在于皮肤号码。我们观察不难发现皮肤号码其实就是英雄id+3为数字组成的,3为数字表示第几个皮肤海报。

在爬取英雄页面之后,我发现这些皮肤海报的地址也是动态生成的。然后在开发者模式(按F12)下发现了每个英雄也对应着一个JS文件


在chamion.js的上面有个Amumu.js这就是阿木木这个英雄对应的JS文件,而里面正好有阿木木这个英雄对应的皮肤代码和皮肤名字

#爬取每个皮肤的名字和皮肤代码
def grab_skin_info():
    heros = generate_hero()
    skins = []
    for h in heros:
        res = requests.get(h.url)
        pat = re.compile(r'"id":"([0-9]*)","num":[0-9]*,"name":"([\w]*|(\\[\w]*)*\s*(\\[\w]*)*)"')
        my_l = pat.findall(res.text)
        for s in my_l:
            skin1 = skin('','')
            skin1.code=s[0]
            skin1.name=eval(repr(s[1]).replace('\\\\', '\\'))#将双斜杠替换成单斜杠,有兴趣的朋友可以将代码放在终端中看一些终端爬下来的是什么样的
            print 'Skin: '+skin1.name+"'s url is generated!"
            skins.append(skin1)
    return skins

至此我们可以总结一下思路:

爬取("http://lol.qq.com/biz/hero/champion.js")拿到所有英雄的名字->通过名字爬取每个英雄对应的js文件拿到皮肤代码和名字->保存到本地

运行结果



完整代码

由于是自己花了不少课余时间的劳动成果,加上缺少C币没钱冲,加上减少对腾讯服务器的负担只好收费了^-^手动表情~~

点击下载完整代码

注意:本教程只用于学习和交流,教程的内容不得用于商业用途,如要引用或转载请声明出处。

代码运行前请删除注释在第一行添加:# -- coding: utf-8 --

如有什么疑问可以在下面留言,我会尽快回复的^_^。

猜你喜欢

转载自blog.csdn.net/u011648373/article/details/80297594