飞道的博客

Python爬取op.gg数据——英雄联盟版本强势英雄推荐

569人阅读  评论(0)

通过爬取韩服op.gg网站的数据,推荐当前版本各路强势英雄(韩服比国服先更新)。

一、op.gg源码及请求头分析

进入op.gg后点击左上角的英雄数据,然后我们可以查看该页面的源码,发现我们需要的数据都在源码中,这就可以使我们的爬取工作轻松许多。该页面还支持多国语言,因此我们要传入相应参数,显示简体中文。我们进入浏览器的开发者模式,可以看到需要在请求头中传入User-Agent和Accept-Language两个参数。

因此构造好请求头。

headers = {
			"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400",
            "Accept-Language":"zh-CN,zh;q=0.9"
                        }

二、源码分析


可以看到在tbody标签有所有上单的英雄数据,在tbody内的每一个tr节点对应每一个英雄的数据。相应的打野的所有英雄数据应该在JUNGLE的tbody标签内。然后我们可以看到tr节点内有个img节点,它有个src属性,是一个url,点开看是文章第一张图片中的优先级。
“//opgg-static.akamaized.net/images/site/champion/icon-champtier-1.png”
这个url中末尾的数字1代表相应的优先级。我们需要把他提取出来。然后胜率这些都在节点的文本中,都可以提取出来。

三、数据提取

有了前面的分析,我们就可以开始提取数据了,这里用pyquery来解析,当然用xpath这些都可以。我们首先来提取上单英雄数据。

import requests
from pyquery import PyQuery as pq

headers = {
			"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400",
            "Accept-Language":"zh-CN,zh;q=0.9"
                        }
html=requests.get("http://www.op.gg/champion/statistics",headers=headers).text

doc=pq(html)
top_mes=doc("tbody.tabItem.champion-trend-tier-TOP tr").items()
#这里遍历tbody的每一个tr节点

for items in top_mes:
    name=items.find("div.champion-index-table__name").text()
    #获取英雄名称
    
    win_chance=items.find("td.champion-index-table__cell--value").text()[:6]
    #获取胜率
    choice=items.find("td.champion-index-table__cell--value").text()[6:]
    #获取登场率
    
    img=items.find("td.champion-index-table__cell--value img").attr("src")
    fisrt_chance="T"+re.match(".*r-(.*?)\.png",img).group(1)
    #获取src属性并提取出优先级

如果我们需要获取五个位置的数据,只需添加遍历所有tbody节点即可。

四、整理数据并写入excel

对于上述的数据我们可以生成一个生成器,在上述代码中加入以下代码

    yield{
    	"name":name,
    	"win_chance":win_chance,
    	"choice":choice,
    	"fisrt_chance":fisrt_chance
    	}

我们将数据写入excel,这里要用到csv标准库。这里在写入是要注意添加encoding和newline两个参数,不然会出现乱码。

import csv
def write_csv(data):
	with open("top.csv", "a", encoding="utf-8-sig", newline='') as file:
        fieldnames = ["name", "win_chance",
                          "choice", "fisrt_chance"]
        writer = csv.DictWriter(file, fieldnames=fieldnames)
        writer.writerow(data)

五、完整代码

import requests
from pyquery import PyQuery as pq
import csv

def get_message(five_mes):
    for items in five_mes:
        name=items.find("div.champion-index-table__name").text()
        #获取英雄名称

        win_chance=items.find("td.champion-index-table__cell--value").text()[:6]
        #获取胜率
        choice=items.find("td.champion-index-table__cell--value").text()[6:]
        #获取登场率

        img=items.find("td.champion-index-table__cell--value img").attr("src")
        fisrt_chance="T"+re.match(".*r-(.*?)\.png",img).group(1)
        #获取src属性并提取出优先级
        yield{
        "name":name,
        "win_chance":win_chance,
        "choice":choice,
        "fisrt_chance":fisrt_chance
        }


def write_csv(data,names):
	#参数names为文件名
    with open(names+".csv", "a", encoding="utf-8-sig", newline='') as file:
        fieldnames = ["name", "win_chance",
                          "choice", "fisrt_chance"]
        writer = csv.DictWriter(file, fieldnames=fieldnames)
        writer.writerow(data)


headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400",
            "Accept-Language":"zh-CN,zh;q=0.9"
                        }
html=requests.get("http://www.op.gg/champion/statistics",headers=headers).text

doc=pq(html)

for position in doc("tbody").items(): 
	#这里遍历五个tbody节点,分别代表五个位置
	
    names=re.match("tabItem champion-trend-tier-(.*)",position.attr("class")).group(1)
    #这里用正则表达式提取出tbody的calss属性的top,mid,adc等作为文件名
    
    for items in get_message(position.find("tr").items()):
    	#这里遍历每一个tbody节点的tr节点并利用get_message函数
        
        write_csv(items,names)
        if items.get("fisrt_chance")=="T1":
        	#输出T1英雄
            print("当前版本T1层级的"+names+"有"+items.get("name"))

结果会创建五个csv文件


**

请多多支持,点赞!

**


转载:https://blog.csdn.net/m0_46412065/article/details/105888078
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场