[python+selenium] LOL Full Hero Full Skin Crawler - меняйте обои на компьютере каждый день

Введение

1.1 Источники спроса

Многие опытные игроки League of Legends признают, что графика LOL сделана хорошо, и многие игроки устанавливают скин своего героя в качестве обоев на свои телефоны, компьютеры или аватары в своих личных социальных аккаунтах.
Как энтузиаст LOL, если вы хотите менять обои на своем компьютере каждый день, как вы сможете просмотреть все скины всех героев LOL? Поскольку скинов слишком много, лучше всего хранить их в папках по имени героя, чтобы их было легче найти.

1.2 Подготовка

python: 3.11.3 (≥3.7)
библиотека селена: 4.9.1
Браузер Firefox: 114.0.2 (64-разрядная версия)
geckodriver: geckodriver-v0.33.0-win64.zip
Как установить geckodriver?

1.3 Анализ идей

В интерфейсе героя LOL есть информация обо всех героях . Нажмите на изображение аватара, чтобы перейти на домашнюю страницу героя . Нажмите на ряд маленьких значков под домашней страницей , чтобы переключиться на разные скины. Щелкните правой кнопкой мыши по скину, чтобы просмотреть ссылку для скачивания . для кожи высокой четкости .
Среди них домашняя страница героя может быть сопоставлена ​​с идентификатором героя (настройка серверной части); ссылка на скин высокого разрешения и ссылка на миниатюру могут быть преобразованы друг в друга.

1.4 Разработка алгоритма процесса

  1) Получите полное имя и идентификатор каждого героя из интерфейса героя LOL
  2) Пройдитесь по всем героям для каждого героя:
  ① Создайте папку на основе полного имени
  ② Перейдите на главную страницу на основе идентификатора
  ③ Получите ссылки на все значки скинов
  ④ ​​Изменить Маленькая иконка-ссылка преобразуется в ссылку на скин высокой четкости
  ⑤ Сохраните скин высокой четкости в папку героя

1.5 План реализации алгоритма

  1) Используйте список для сохранения данных для обхода
  2) Используйте веб-драйвер (geckodriver) для получения информации о веб-странице, нахождения элементов и загрузки ресурсов
  3) Используйте try-кроме для обработки нештатных ситуаций
  4) Используйте time.sleep для обработки нештатных ситуаций обратное сканирование
  5) Используйте str.replace для замены специальных символов в "K//DA"

2. Анализ кода

2.1 Получите имена и идентификаторы всех героев

Обзор всех героев
Используйте класс «imgtextlist», чтобы найти блоки элементов всех героев, затем получите информацию обо всех тегах «li» и сохраните их в списке для дальнейшего анализа.

# 获取全部英雄概览信息
def getHeros(driver):
    # 英雄联盟英雄信息前置界面
    driver.get('https://lol.qq.com/data/info-heros.shtml')
    # 获取全部英雄的信息概览
    heros_res = driver.find_element(By.CLASS_NAME, "imgtextlist")
    # 获取每个英雄信息的列表
    heros = heros_res.find_elements(By.TAG_NAME, "li")
    return heros

Полное имя и идентификатор героя
Дальнейший анализ позволяет получить полное имя и идентификатор героя. Здесь для возврата результатов используются две функции соответственно:

# 获取英雄名称,用于单独建立文件夹存储
def getHerosName(heros):
    hero_name = []  # 记录英雄全名,如“德邦总管 赵信”
    for h in heros:
        hero_name.append(h.find_element(By.TAG_NAME, "a").get_attribute("title"))  # 获取英雄全名
    print("hero_name:", hero_name)
    return hero_name
# 获取英雄排名id,用于后续获取皮肤图片等
def getHerosId(heros):
    hero_id = []  # 记录英雄的排名id
    for h in heros:
        hero_href = h.find_element(By.TAG_NAME, "a").get_attribute("href")  # 获取英雄个人链接
        hero_id.append(hero_href.split('=')[1])  # 获取英雄的排名id
    return hero_id

Примечание : Очень важно получить ID, так как ID не соответствует порядку запуска героев.Например, ID нового героя Минчжу равен 902, а в LOL явно не так много героев. Для получения скинов необходимо иметь ID героя. (Интересно, это механизм предотвращения сканирования, намеренно установленный чиновником?) Вы также можете напрямую сохранить ссылку перехода героя для прыжка .

2.2 Пройти всех героев

    total_num = len(hero_name)
    for i in range(total_num):

2.2.1 Создайте папки для каждого героя

# 为每一个英雄单独创建文件夹,来保存皮肤
def createPath(name):
    global savePath
    filepath = f"{
      
      savePath}{
      
      name}\\"  # 为每一个英雄单独创建一个路径,以其全名命名
    if not os.path.exists(filepath):
        os.makedirs(filepath)
        print(filepath + "文件夹创建成功!")

2.2.2 Найдите главную страницу по идентификатору

Перейти к основному интерфейсу героя по его идентификатору:

url = "https://lol.qq.com/data/info-defail.shtml?id=" + str(n)  # 根据 id 可以获取英雄的个人链接

Позиция маленького значка
Затем вы можете найти маленький значок и ссылку на него:

driver.get(url)
skins_res = driver.find_element(By.ID, "skinNAV")  # 定位到皮肤栏
skins = skins_res.find_elements(By.TAG_NAME, "img")  # 获取小图标的列表
for skin in skins:
    skin_name = skin.get_attribute("alt")
    skin_link_small = skin.get_attribute("src")  # 获取每个小图的链接
    # https://game.gtimg.cn/images/lol/act/img/skin/small_0b940af1-bd04-4f9a-a909-427cabea21b1.jpg

2.2.3 Преобразование небольших ссылок-значков в ссылки на изображения высокой четкости

Ссылка на маленький значок:
https://game.gtimg.cn/images/lol/act/img/skin/ small _0b940af1-bd04-4f9a-a909-427cabea21b1.jpg
Ссылка на изображение с высоким разрешением:
https://game.gtimg.cn/images/lol/act/img/skin/ big _0b940af1-bd04-4f9a-a909-427cabea21b1.jpg

Это достигается простой заменой строк:

skin_link_big = str(skin_link_small).replace("small", "big")  # 替换为大图的链接
# https://game.gtimg.cn/images/lol/act/img/skin/big_0b940af1-bd04-4f9a-a909-427cabea21b1.jpg

2.2.4 Сохранение изображений скинов высокой четкости

При определении пути хранения изображения учитывайте влияние строки «K/DA» и замените «/» на «», чтобы не идентифицировать его как путь и не сообщать об ошибке:

filename = f"{
      
      savePath}{
      
      hero_name[i]}\\{
      
      str(skin_name).replace('/', '')}.jpg"  # 防止 K/DA 下载出错

Затем вы можете начать скачивание:

try:
    urlretrieve(skin_link_big, filename=filename)
except urllib.error.ContentTooShortError:
    driver.sleep(5)
    urlretrieve(skin_link_big, filename=filename)
except:
    print("未知错误!")
print(skin_name + "图片下载完成!")  # 输出提示:英雄的该个皮肤图片下载完成

3. Запустите скриншоты

Распечатать данные подсказки во время работы:
Распечатка данных во время работы
Посмотреть сохраненный скин в папке:
папка скина
Предварительный просмотр скина «Демон Меча»

4. Полный код

import os
import time
import urllib
from selenium import webdriver
from urllib.request import urlretrieve
from selenium.webdriver.common.by import By

# 模拟请求头
user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/" \
             "605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15"
# 配置 webdriver
opt = webdriver.FirefoxOptions()
opt.add_argument('--user-agent=%s' % user_agent)


# opt.add_argument("--headless")      # 开启此选项,浏览器不会显示动作


# 获取全部英雄概览信息
def getHeros(driver):
    # 英雄联盟英雄信息前置界面
    driver.get('https://lol.qq.com/data/info-heros.shtml')
    # 获取全部英雄的信息概览
    heros_res = driver.find_element(By.CLASS_NAME, "imgtextlist")
    # 获取每个英雄信息的列表
    heros = heros_res.find_elements(By.TAG_NAME, "li")
    return heros


# 获取英雄名称,用于单独建立文件夹存储
def getHerosName(heros):
    hero_name = []  # 记录英雄全名,如“德邦总管 赵信”
    for h in heros:
        hero_name.append(h.find_element(By.TAG_NAME, "a").get_attribute("title"))  # 获取英雄全名
    print("hero_name:", hero_name)
    return hero_name


# 获取英雄排名id,用于后续获取皮肤图片等
def getHerosId(heros):
    hero_id = []  # 记录英雄的排名id
    for h in heros:
        hero_href = h.find_element(By.TAG_NAME, "a").get_attribute("href")  # 获取英雄个人链接
        hero_id.append(hero_href.split('=')[1])  # 获取英雄的排名id
    return hero_id


# 为每一个英雄单独创建文件夹,来保存皮肤
def createPath(name):
    global savePath
    filepath = f"{
      
      savePath}{
      
      name}\\"  # 为每一个英雄单独创建一个路径,以其全名命名
    if not os.path.exists(filepath):
        os.makedirs(filepath)
        print(filepath + "文件夹创建成功!")


# 获取英雄皮肤,规避反爬机制,并进行异常处理
def getAndSaveSkins(driver, hero_name, hero_id):
    global savePath
    # 遍历全部英雄
    total_num = len(hero_name)
    for i in range(total_num):
        createPath(hero_name[i])    # 为每个英雄单独开辟一个文件夹
        n = hero_id[i]  # 提取英雄对应的id。注意:id 和 name 列表顺序并不是一一对应的,因此有必要单独获取
        driver.implicitly_wait(10)
        url = "https://lol.qq.com/data/info-defail.shtml?id=" + str(n)  # 根据 id 可以获取英雄的个人链接
        driver.get(url)
        skins_res = driver.find_element(By.ID, "skinNAV")  # 定位到皮肤栏
        skins = skins_res.find_elements(By.TAG_NAME, "img")  # 获取小图标的列表

        for skin in skins:
            skin_name = skin.get_attribute("alt")
            skin_link_small = skin.get_attribute("src")  # 获取每个小图的链接
            # https://game.gtimg.cn/images/lol/act/img/skin/small_0b940af1-bd04-4f9a-a909-427cabea21b1.jpg
            skin_link_big = str(skin_link_small).replace("small", "big")  # 替换为大图的链接
            # https://game.gtimg.cn/images/lol/act/img/skin/big_0b940af1-bd04-4f9a-a909-427cabea21b1.jpg

            filename = f"{
      
      savePath}{
      
      hero_name[i]}\\{
      
      str(skin_name).replace('/', '')}.jpg"  # 防止 K/DA 下载出错
            try:
                urlretrieve(skin_link_big, filename=filename)
            except urllib.error.ContentTooShortError:
                driver.sleep(5)
                urlretrieve(skin_link_big, filename=filename)
            except:
                print("未知错误!")
            print(skin_name + "图片下载完成!")  # 输出提示:英雄的该个皮肤图片下载完成
        print("************" + hero_name[i] + "全部图片下载完毕!************\n")  # 输出提示:该英雄的全部高清皮肤下载完成
        # time.sleep(2)   # 设置时间间隔,规避反爬机制


if __name__ == "__main__":
    savePath = "D:\\lolSkins\\"
    driver = webdriver.Firefox(options=opt)  # 启动 webdriver
    # 如果 driver 文件没有放在系统路径下,可以指定文件路径,也可以不带“.exe”
    # driver = webdriver.Firefox(executable_path='D:/driver/geckodriver.exe', options=opt)
    # 新版 selenium 推荐使用 service 写法。个人推荐第一种,把 webdriver 放在系统路径下
    # service = Service(executable_path=executable_path='D:/driver/geckodriver.exe')
    # driver = webdriver.Firefox(service=service,options=opt)
    driver.implicitly_wait(10)  # 设置界面等待的最长时间
    heros = getHeros(driver)  # 获取英雄信息概览
    hero_name = getHerosName(heros)  # 获取英雄名,用于存储皮肤
    hero_id = getHerosId(heros)  # 获取英雄id,用于爬取皮肤
    getAndSaveSkins(driver, hero_name, hero_id)  # 获取皮肤并保存到对应的文件夹中

PS: Пожалуйста, не используйте данный метод в коммерческих целях. Используйте интернет-ресурсы разумно в пределах, разрешенных законом! Если вы хотите найти еще больше интересных применений Python, обратите внимание на последующие обновления~

Supongo que te gusta

Origin blog.csdn.net/weixin_44844635/article/details/131341447
Recomendado
Clasificación