Browse Source

feat(pokemon_tcg_spider): 添加繁中详情页信息爬取及日文卡包名称列表

- 新增pokemon_tcg_spider/fanz_update.py,实现爬取详情页展开包信息及发售日期
- 通过数据库查询展开包发布日期并格式化存储
- 实现主函数调度,支持异常捕获和日志记录
- 新增pokemon_tcg_spider/jp_set_name_list.py,提供详尽的日文卡包名称与对应URL映射列表
- 两文件均添加文件头注释,方便维护管理
charley 1 month ago
parent
commit
ec03abdfae

+ 87 - 0
pokemon_tcg_spider/fanz_update.py

@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+# Author : Charley
+# Python : 3.10.8
+# Date   : 2026/1/4 18:55
+import inspect
+from datetime import datetime
+import requests
+import user_agent
+from loguru import logger
+from parsel import Selector
+from tenacity import retry, stop_after_attempt, wait_fixed
+from mysql_pool import MySQLConnectionPool
+
+headers = {
+    # "referer": "https://asia.pokemon-card.com/tw/card-search/list/",
+    "user-agent": user_agent.generate_user_agent()
+}
+
+crawler_language = "繁中"
+
+
+def get_details(log, sql_id_detail_url: tuple, sql_pool):
+    log.debug(f'Request get_details for sql_id_detail_url: {sql_id_detail_url}')
+    # url = "https://asia.pokemon-card.com/tw/card-search/detail/13958/"
+    url = sql_id_detail_url[1]
+    # response = requests.get(url, headers=headers, timeout=10, proxies=get_proxys(log))
+    response = requests.get(url, headers=headers, timeout=10)
+    # print(response.text)
+    response.raise_for_status()
+
+    selector = Selector(response.text)
+    pg_label = selector.xpath('//section[@class="expansionLinkColumn"]/a/text()').get()
+    pg_label = pg_label.strip() if pg_label else None
+
+    # expansion_release_time 为'03-28-2025'格式  转换为正常的 年月日
+    sql_expansion_release_time = sql_pool.select_one(
+        f"select expansion_series, expansion_release_time from pokemon_fanz_category where expansion_title = '{pg_label}' and crawler_language = '{crawler_language}'")
+    date_obj = datetime.strptime(sql_expansion_release_time[1], '%m-%d-%Y')
+    expansion_release_time = date_obj.strftime('%Y-%m-%d')
+
+    major_category_name = sql_expansion_release_time[0]
+
+    data_dict = {
+        "major_category_name": major_category_name,
+        "pg_label": pg_label,
+        "sales_date": expansion_release_time
+    }
+    log.debug(f'data_dict -> {data_dict}')
+
+    sql_pool.update_one_or_dict(
+        table="pokemon_card_record",
+        data=data_dict,
+        condition={"id": sql_id_detail_url[0]}
+    )
+
+
+def fz_pokemon_main(log):
+    """
+    主函数
+    """
+    log.info(f'开始运行 {inspect.currentframe().f_code.co_name} 爬虫任务.............................................')
+
+    # 配置 MySQL 连接池
+    sql_pool = MySQLConnectionPool(log=log)
+    if not sql_pool.check_pool_health():
+        log.error("数据库连接池异常")
+        raise RuntimeError("数据库连接池异常")
+
+    try:
+        # 获取商品详情
+        log.debug(f"........... 获取商品详情 ..........")
+        sql_ietm_id_list = sql_pool.select_all(
+            f"SELECT id, detail_url FROM pokemon_card_record WHERE pg_label IS NULL AND crawler_language='{crawler_language}'")
+        for item_id in sql_ietm_id_list:
+            try:
+                get_details(log, item_id, sql_pool)
+            except Exception as e:
+                log.error(f"Request get_details error: {e}")
+
+    except Exception as e:
+        log.error(f'{inspect.currentframe().f_code.co_name} error: {e}')
+    finally:
+        log.info(f'爬虫程序 {inspect.currentframe().f_code.co_name} 运行结束,等待下一轮的采集任务............')
+
+
+if __name__ == '__main__':
+    fz_pokemon_main(logger)

+ 774 - 0
pokemon_tcg_spider/jp_set_name_list.py

@@ -0,0 +1,774 @@
+# -*- coding: utf-8 -*-
+# Author : Charley
+# Python : 3.10.8
+# Date   : 2025/11/26 19:00
+SET_JP_NAME_LIST = [
+    {'set_name': 'Theater Limited VS Pack', 'url_value': 'theater-limited-vs-pack'},
+    {'set_name': 'S7D: Skyscraping Perfection', 'url_value': 's7d-skyscraping-perfection'},
+    {'set_name': 'SV4a: Shiny Treasure ex', 'url_value': 'sv4a-shiny-treasure-ex'},
+    {'set_name': 'Pokemon Card Design Contest', 'url_value': 'pokemon-card-design-contest'},
+    {'set_name': '11th Movie Commemoration Set', 'url_value': '11th-movie-commemoration-set'},
+    {'set_name': 'smE: Solgaleo-GX & Lunala-GX Legendary Starter Set',
+     'url_value': 'sme-solgaleo-gx-and-lunala-gx-legendary-starter-set'},
+    {'set_name': 'BW5: Dragon Blade', 'url_value': 'bw5-dragon-blade'},
+    {'set_name': 'PokePark Forest', 'url_value': 'pokepark-forest'},
+    {'set_name': 'smP2: Great Detective Pikachu', 'url_value': 'smp2-great-detective-pikachu'},
+    {'set_name': 'BKB: Black Kyurem-EX Battle Strength Deck',
+     'url_value': 'bkb-black-kyurem-ex-battle-strength-deck'},
+    {'set_name': 'smA: Sun & Moon Starter Set', 'url_value': 'sma-sun-and-moon-starter-set'},
+    {'set_name': 'sC2: Charizard Starter Set VMAX 2', 'url_value': 'sc2-charizard-starter-set-vmax-2'},
+    {'set_name': 'DP5: Cry from the Mysterious', 'url_value': 'dp5-cry-from-the-mysterious'},
+    {'set_name': 'SM10a: GG End', 'url_value': 'sm10a-gg-end'},
+    {'set_name': 'Movie Commemoration VS Pack', 'url_value': 'movie-commemoration-vs-pack'},
+    {'set_name': 'Psychic Quick Construction Pack', 'url_value': 'psychic-quick-construction-pack'},
+    {'set_name': 'XYG: Zygarde-EX Perfect Battle Deck',
+     'url_value': 'xyg-zygarde-ex-perfect-battle-deck'},
+    {'set_name': "Mirage's Mew Constructed Starter Deck",
+     'url_value': 'mirages-mew-constructed-starter-deck'},
+    {'set_name': 'Awakening Legends', 'url_value': 'awakening-legends'},
+    {'set_name': 'Infernape vs Gallade SP Deck Kit (Infernape)',
+     'url_value': 'infernape-vs-gallade-sp-deck-kit-infernape'},
+    {'set_name': 'BW1: Black Collection', 'url_value': 'bw1-black-collection'},
+    {'set_name': 'Rocket Gang', 'url_value': 'rocket-gang'},
+    {'set_name': 'SM8: Super-Burst Impact', 'url_value': 'sm8-super-burst-impact'},
+    {'set_name': 'SV: ex Starter Set Pikachu ex & Pawmot',
+     'url_value': 'sv-ex-starter-set-pikachu-ex-and-pawmot'},
+    {'set_name': 'PLAY Promotional cards', 'url_value': 'play-promotional-cards'},
+    {'set_name': 'L3: Clash at the Summit', 'url_value': 'l3-clash-at-the-summit'},
+    {'set_name': "McDonald's Pokémon-e Minimum Pack", 'url_value': 'mcdonalds-pokémon-e-minimum-pack'},
+    {'set_name': 'Offense and Defense of the Furthest Ends',
+     'url_value': 'offense-and-defense-of-the-furthest-ends'},
+    {'set_name': 'Emerald Gift Box (Deoxys)', 'url_value': 'emerald-gift-box-deoxys'},
+    {'set_name': 'SM9b: Full Metal Wall', 'url_value': 'sm9b-full-metal-wall'},
+    {'set_name': 'BW7: Plasma Gale', 'url_value': 'bw7-plasma-gale'},
+    {'set_name': 'S10P: Space Juggler', 'url_value': 's10p-space-juggler'},
+    {'set_name': 'sB: Sword & Shield Premium Trainer Box',
+     'url_value': 'sb-sword-and-shield-premium-trainer-box'},
+    {'set_name': 'XY8-Bb: Blue Shock', 'url_value': 'xy8-bb-blue-shock'},
+    {'set_name': 'SV11W: White Flare', 'url_value': 'sv11w-white-flare'},
+    {'set_name': 'Vending Machine cards Series 2 (Red)',
+     'url_value': 'vending-machine-cards-series-2-red'},
+    {'set_name': 'Golden Sky, Silvery Ocean', 'url_value': 'golden-sky-silvery-ocean'},
+    {'set_name': 'BKW: White Kyurem-EX Battle Strength Deck',
+     'url_value': 'bkw-white-kyurem-ex-battle-strength-deck'},
+    {'set_name': 'LL: Lost Link', 'url_value': 'll-lost-link'},
+    {'set_name': 'm1L: Mega Brave', 'url_value': 'm1l-mega-brave'},
+    {'set_name': 'DPt Gift Box (Chimchar)', 'url_value': 'dpt-gift-box-chimchar'},
+    {'set_name': 's8a-P: Promo Card Pack 25th Anniversary Edition',
+     'url_value': 's8a-p-promo-card-pack-25th-anniversary-edition'},
+    {'set_name': 'Arceus LV.X Deck: Grass & Fire', 'url_value': 'arceus-lvx-deck-grass-and-fire'},
+    {'set_name': 'SM4S: Awakened Heroes', 'url_value': 'sm4s-awakened-heroes'},
+    {'set_name': "Everyone's Exciting Battle", 'url_value': 'everyones-exciting-battle'},
+    {'set_name': 'Battle Starter Deck (Blastoise)', 'url_value': 'battle-starter-deck-blastoise'},
+    {'set_name': 'Battle Starter Deck (Torterra)', 'url_value': 'battle-starter-deck-torterra'},
+    {'set_name': 'Rayquaza Constructed Starter Deck', 'url_value': 'rayquaza-constructed-starter-deck'},
+    {'set_name': 'Dialga LV.X Constructed Standard Deck',
+     'url_value': 'dialga-lvx-constructed-standard-deck'},
+    {'set_name': 'SV: Premium Trainer Box ex', 'url_value': 'sv-premium-trainer-box-ex'},
+    {'set_name': 'BKR: Reshiram-EX Battle Strength Deck',
+     'url_value': 'bkr-reshiram-ex-battle-strength-deck'},
+    {'set_name': 'Intense Fight in the Destroyed Sky',
+     'url_value': 'intense-fight-in-the-destroyed-sky'},
+    {'set_name': 'CP4: Premium Champion Pack', 'url_value': 'cp4-premium-champion-pack'},
+    {'set_name': 'DP-P Promotional cards', 'url_value': 'dp-p-promotional-cards'},
+    {'set_name': 'XYA: M Charizard-EX Mega Battle Deck',
+     'url_value': 'xya-m-charizard-ex-mega-battle-deck'},
+    {'set_name': 'CS1: Journey Partners Collection Sheet',
+     'url_value': 'cs1-journey-partners-collection-sheet'},
+    {'set_name': 'SV: Ceruledge ex Stellar Tera Type Starter Set',
+     'url_value': 'sv-ceruledge-ex-stellar-tera-type-starter-set'},
+    {'set_name': 'CP1: Magma Gang vs Aqua Gang: Double Crisis',
+     'url_value': 'cp1-magma-gang-vs-aqua-gang-double-crisis'},
+    {'set_name': 'SM2+: Facing a New Trial', 'url_value': 'sm2plus-facing-a-new-trial'},
+    {'set_name': 'Battle Theme Deck: Victini', 'url_value': 'battle-theme-deck-victini'},
+    {'set_name': 'BW-P Promotional cards', 'url_value': 'bw-p-promotional-cards'},
+    {'set_name': 'SM2K: Islands Await You', 'url_value': 'sm2k-islands-await-you'},
+    {'set_name': 'Team Plasma Battle Gift Set', 'url_value': 'team-plasma-battle-gift-set'},
+    {'set_name': 'M Master Deck Build Box Speed Style',
+     'url_value': 'm-master-deck-build-box-speed-style'},
+    {'set_name': 'S8b: VMAX Climax', 'url_value': 's8b-vmax-climax'},
+    {'set_name': 'BW3: Hail Blizzard', 'url_value': 'bw3-hail-blizzard'},
+    {'set_name': 'Gold, Silver, to a New World...', 'url_value': 'gold-silver-to-a-new-world'},
+    {'set_name': 'SM1S: Collection Sun', 'url_value': 'sm1s-collection-sun'},
+    {'set_name': 'Master Kit (Torchic)', 'url_value': 'master-kit-torchic'},
+    {'set_name': 'smJ: Tag Team GX Premium Trainer Box',
+     'url_value': 'smj-tag-team-gx-premium-trainer-box'},
+    {'set_name': 'S10a: Dark Phantasma', 'url_value': 's10a-dark-phantasma'},
+    {'set_name': 'SM1+: Sun & Moon', 'url_value': 'sm1plus-sun-and-moon'},
+    {'set_name': 'Mewtwo vs Genesect Deck Kit (Mewtwo)',
+     'url_value': 'mewtwo-vs-genesect-deck-kit-mewtwo'},
+    {'set_name': 'S2: Rebellion Crash', 'url_value': 's2-rebellion-crash'},
+    {'set_name': 'SV6: Transformation Mask', 'url_value': 'sv6-transformation-mask'},
+    {'set_name': 'Holon Research Tower', 'url_value': 'holon-research-tower'},
+    {'set_name': 'S6H: Silver Lance', 'url_value': 's6h-silver-lance'},
+    {'set_name': 'SM12: Alter Genesis', 'url_value': 'sm12-alter-genesis'},
+    {'set_name': 'PtM: Mewtwo LV.X Collection Pack', 'url_value': 'ptm-mewtwo-lvx-collection-pack'},
+    {'set_name': 'SM6b: Champion Road', 'url_value': 'sm6b-champion-road'},
+    {'set_name': 'How I Became a Pokemon Card', 'url_value': 'how-i-became-a-pokemon-card'},
+    {'set_name': 'Rampardos the Attacker Constructed Half Deck',
+     'url_value': 'rampardos-the-attacker-constructed-half-deck'},
+    {'set_name': 'SV8: Super Electric Breaker', 'url_value': 'sv8-super-electric-breaker'},
+    {'set_name': 'Battle Road', 'url_value': 'battle-road'},
+    {'set_name': 'XY-By: Collection Y', 'url_value': 'xy-by-collection-y'},
+    {'set_name': 'Challenge from the Darkness', 'url_value': 'challenge-from-the-darkness'},
+    {'set_name': 'Mystery of the Fossils', 'url_value': 'mystery-of-the-fossils'},
+    {'set_name': '64 Mario Stadium Best Photo Contest',
+     'url_value': '64-mario-stadium-best-photo-contest'},
+    {'set_name': 'Darkness, and to Light...', 'url_value': 'darkness-and-to-light'},
+    {'set_name': 'Mirage Forest', 'url_value': 'mirage-forest'},
+    {'set_name': 'SM6a: Dragon Storm', 'url_value': 'sm6a-dragon-storm'},
+    {'set_name': "SV: ex Starter Set Marnie's Morpeko & Grimmsnarl ex",
+     'url_value': 'sv-ex-starter-set-marnies-morpeko-and-grimmsnarl-ex'},
+    {'set_name': 'Unnumbered World Championships', 'url_value': 'unnumbered-world-championships'},
+    {'set_name': 'SV: ex Starter Set Sprigatito & Lucario ex',
+     'url_value': 'sv-ex-starter-set-sprigatito-and-lucario-ex'},
+    {'set_name': 'BK: Cobalion Battle Strength Deck', 'url_value': 'bk-cobalion-battle-strength-deck'},
+    {'set_name': 'S10D: Time Gazer', 'url_value': 's10d-time-gazer'},
+    {'set_name': 'Meganium Constructed Starter Deck', 'url_value': 'meganium-constructed-starter-deck'},
+    {'set_name': 'DP3: Shining Darkness', 'url_value': 'dp3-shining-darkness'},
+    {'set_name': 'T Promotional cards', 'url_value': 't-promotional-cards'},
+    {'set_name': 'Dragon Selection', 'url_value': 'dragon-selection'},
+    {'set_name': 'XY5-Bg: Gaia Volcano', 'url_value': 'xy5-bg-gaia-volcano'},
+    {'set_name': 'sA: Fire Starter Set V', 'url_value': 'sa-fire-starter-set-v'},
+    {'set_name': 'SNP: Raichu BREAK Evolution Pack', 'url_value': 'snp-raichu-break-evolution-pack'},
+    {'set_name': 'S2a: Explosive Walker', 'url_value': 's2a-explosive-walker'},
+    {'set_name': 'Pt2: Bonds to the End of Time', 'url_value': 'pt2-bonds-to-the-end-of-time'},
+    {'set_name': 'SV11B: Black Bolt', 'url_value': 'sv11b-black-bolt'},
+    {'set_name': "SM0: Pikachu's New Friends", 'url_value': 'sm0-pikachus-new-friends'},
+    {'set_name': 'Arceus LV.X Deck: Lightning & Psychic',
+     'url_value': 'arceus-lvx-deck-lightning-and-psychic'},
+    {'set_name': 'S1W: Sword', 'url_value': 's1w-sword'},
+    {'set_name': 'Treecko Constructed Starter Deck', 'url_value': 'treecko-constructed-starter-deck'},
+    {'set_name': "Ocean's Kyogre ex Constructed Starter Deck",
+     'url_value': 'oceans-kyogre-ex-constructed-starter-deck'},
+    {'set_name': 'S-P: Sword & Shield Promos', 'url_value': 's-p-sword-and-shield-promos'},
+    {'set_name': 'S1a: VMAX Rising', 'url_value': 's1a-vmax-rising'},
+    {'set_name': 'BW2: Red Collection', 'url_value': 'bw2-red-collection'},
+    {'set_name': 'SV: ex Starter Set Fuecoco & Ampharos ex',
+     'url_value': 'sv-ex-starter-set-fuecoco-and-ampharos-ex'},
+    {'set_name': 'BW5: Dragon Blast', 'url_value': 'bw5-dragon-blast'},
+    {'set_name': 'SVM: Generations Start Decks', 'url_value': 'svm-generations-start-decks'},
+    {'set_name': 'Grass Quick Construction Pack', 'url_value': 'grass-quick-construction-pack'},
+    {'set_name': 'SM7b: Fairy Rise', 'url_value': 'sm7b-fairy-rise'},
+    {'set_name': 'SM6: Forbidden Light', 'url_value': 'sm6-forbidden-light'},
+    {'set_name': 'Holon Phantom', 'url_value': 'holon-phantom'},
+    {'set_name': 'SV: Mewtwo ex Terastal Starter Set',
+     'url_value': 'sv-mewtwo-ex-terastal-starter-set'},
+    {'set_name': 'Holon Research Tower Water Quarter Deck',
+     'url_value': 'holon-research-tower-water-quarter-deck'},
+    {'set_name': 'sA: Lightning Starter Set V', 'url_value': 'sa-lightning-starter-set-v'},
+    {'set_name': 'Base Expansion Pack', 'url_value': 'base-expansion-pack'},
+    {'set_name': 'SV: ex Special Set', 'url_value': 'sv-ex-special-set'},
+    {'set_name': 'smF: Ultra Sun & Ultra Moon Premium Trainer Box',
+     'url_value': 'smf-ultra-sun-and-ultra-moon-premium-trainer-box'},
+    {'set_name': 'SM3+: Shining Legends', 'url_value': 'sm3plus-shining-legends'},
+    {'set_name': 'sH: Sword & Shield Family Pokemon Card Game',
+     'url_value': 'sh-sword-and-shield-family-pokemon-card-game'},
+    {'set_name': 'SS: Gengar VMAX High-Class Deck', 'url_value': 'ss-gengar-vmax-high-class-deck'},
+    {'set_name': 'sA: Fighting Starter Set V', 'url_value': 'sa-fighting-starter-set-v'},
+    {'set_name': 'Fighting Quick Construction Pack', 'url_value': 'fighting-quick-construction-pack'},
+    {'set_name': 'Intro Pack Neo (Chikorita)', 'url_value': 'intro-pack-neo-chikorita'},
+    {'set_name': 'S5a: Peerless Fighters', 'url_value': 's5a-peerless-fighters'},
+    {'set_name': 'WCS23: 2023 World Championships Yokohama Deck: Pikachu',
+     'url_value': 'wcs23-2023-world-championships-yokohama-deck-pikachu'},
+    {'set_name': 'SM10b: Sky Legend', 'url_value': 'sm10b-sky-legend'},
+    {'set_name': 'Intro Pack (Squirtle)', 'url_value': 'intro-pack-squirtle'},
+    {'set_name': 'XYB: Dialga-EX + Aegislash-EX Hyper Metal Chain Deck',
+     'url_value': 'xyb-dialga-ex-plus-aegislash-ex-hyper-metal-chain-deck'},
+    {'set_name': 'S5I: Single Strike Master', 'url_value': 's5i-single-strike-master'},
+    {'set_name': 'Pokemon Card Fan Club', 'url_value': 'pokemon-card-fan-club'},
+    {'set_name': 'S4a: Shiny Star V', 'url_value': 's4a-shiny-star-v'},
+    {'set_name': 'PtR: Regigigas LV.X Collection Pack',
+     'url_value': 'ptr-regigigas-lvx-collection-pack'},
+    {'set_name': 'Heatran vs Regigigas Deck Kit', 'url_value': 'heatran-vs-regigigas-deck-kit'},
+    {'set_name': 'BW1: White Collection', 'url_value': 'bw1-white-collection'},
+    {'set_name': 'Xerneas Half Deck', 'url_value': 'xerneas-half-deck'},
+    {'set_name': 'XY Beginning Set', 'url_value': 'xy-beginning-set'},
+    {'set_name': 'SM12a: TAG TEAM GX: Tag All Stars', 'url_value': 'sm12a-tag-team-gx-tag-all-stars'},
+    {'set_name': 'Expansion Pack', 'url_value': 'expansion-pack'},
+    {'set_name': 'SV: Terastal Charizard ex Battle Master Deck',
+     'url_value': 'sv-terastal-charizard-ex-battle-master-deck'},
+    {'set_name': 'SV4K: Ancient Roar', 'url_value': 'sv4k-ancient-roar'},
+    {'set_name': 'SV: Venusaur, Charizard & Blastoise Special Deck Set',
+     'url_value': 'sv-venusaur-charizard-and-blastoise-special-deck-set'},
+    {'set_name': 'SM: The Best of XY', 'url_value': 'sm-the-best-of-xy'},
+    {'set_name': 'sA: Grass Starter Set V', 'url_value': 'sa-grass-starter-set-v'},
+    {'set_name': 'DP4: Moonlit Pursuit', 'url_value': 'dp4-moonlit-pursuit'},
+    {'set_name': 'Lightning Quick Construction Pack', 'url_value': 'lightning-quick-construction-pack'},
+    {'set_name': 'DP1: Space-Time Creation', 'url_value': 'dp1-space-time-creation'},
+    {'set_name': 'Neo Premium File 1', 'url_value': 'neo-premium-file-1'},
+    {'set_name': 'Gift Box Mew - Lucario (Lucario Quarter Deck)',
+     'url_value': 'gift-box-mew-lucario-lucario-quarter-deck'},
+    {'set_name': 'S4: Amazing Volt Tackle', 'url_value': 's4-amazing-volt-tackle'},
+    {'set_name': 'SV8a: Terastal Fest ex', 'url_value': 'sv8a-terastal-fest-ex'},
+    {'set_name': 'sC: Charizard Starter Set VMAX', 'url_value': 'sc-charizard-starter-set-vmax'},
+    {'set_name': "Leaders' Stadium", 'url_value': 'leaders-stadium'},
+    {'set_name': 'XY11-Br: Cruel Traitor', 'url_value': 'xy11-br-cruel-traitor'},
+    {'set_name': 'SV-P Promotional Cards', 'url_value': 'sv-p-promotional-cards'},
+    {'set_name': 'Battle Starter Deck (Magmortar)', 'url_value': 'battle-starter-deck-magmortar'},
+    {'set_name': 'L1: HeartGold Collection', 'url_value': 'l1-heartgold-collection'},
+    {'set_name': 'Pokemon Card Information Promotional cards',
+     'url_value': 'pokemon-card-information-promotional-cards'},
+    {'set_name': 'sLD: Darkrai Starter Set VSTAR', 'url_value': 'sld-darkrai-starter-set-vstar'},
+    {'set_name': 'CP2: Legendary Shine Collection', 'url_value': 'cp2-legendary-shine-collection'},
+    {'set_name': 'S12a: VSTAR Universe', 'url_value': 's12a-vstar-universe'},
+    {'set_name': 'Pokemon Jungle', 'url_value': 'pokemon-jungle'},
+    {'set_name': 'Mewtwo vs Genesect Deck Kit (Genesect)',
+     'url_value': 'mewtwo-vs-genesect-deck-kit-genesect'},
+    {'set_name': 'SV2P: Snow Hazard', 'url_value': 'sv2p-snow-hazard'},
+    {'set_name': 'J Promotional cards', 'url_value': 'j-promotional-cards'},
+    {'set_name': 'L2: Steelix Constructed Standard Deck',
+     'url_value': 'l2-steelix-constructed-standard-deck'},
+    {'set_name': 'XY11-Bb: Fever-Burst Fighter', 'url_value': 'xy11-bb-fever-burst-fighter'},
+    {'set_name': 'SM8a: Dark Order', 'url_value': 'sm8a-dark-order'},
+    {'set_name': 'sA: Water Starter Set V', 'url_value': 'sa-water-starter-set-v'},
+    {'set_name': 'Gym Challenge', 'url_value': 'gym-challenge'},
+    {'set_name': 'Unnumbered Promotional cards', 'url_value': 'unnumbered-promotional-cards'},
+    {'set_name': 'SM11b: Dream League', 'url_value': 'sm11b-dream-league'},
+    {'set_name': 'CP5: Mythical & Legendary Dream Shine Collection',
+     'url_value': 'cp5-mythical-and-legendary-dream-shine-collection'},
+    {'set_name': 'Master Kit (Bulbasaur)', 'url_value': 'master-kit-bulbasaur'},
+    {'set_name': 'SVN: Battle Partners Deck Build Box',
+     'url_value': 'svn-battle-partners-deck-build-box'},
+    {'set_name': 'Master Deck Build Box EX', 'url_value': 'master-deck-build-box-ex'},
+    {'set_name': '10th Movie Commemoration Set', 'url_value': '10th-movie-commemoration-set'},
+    {'set_name': "Entry Pack '08", 'url_value': 'entry-pack-08'},
+    {'set_name': 'Black Deck Kit', 'url_value': 'black-deck-kit'},
+    {'set_name': 'sLL: Lucario Starter Set VSTAR', 'url_value': 'sll-lucario-starter-set-vstar'},
+    {'set_name': 'Flight of Legends', 'url_value': 'flight-of-legends'},
+    {'set_name': 'SV3a: Raging Surf', 'url_value': 'sv3a-raging-surf'},
+    {'set_name': 'S3a: Legendary Heartbeat', 'url_value': 's3a-legendary-heartbeat'},
+    {'set_name': 'Entry Pack DPt (Dialga)', 'url_value': 'entry-pack-dpt-dialga'},
+    {'set_name': 'Gift Box Mew - Lucario (Pokemon Star)',
+     'url_value': 'gift-box-mew-lucario-pokemon-star'},
+    {'set_name': 'BKZ: Zekrom-EX Battle Strength Deck',
+     'url_value': 'bkz-zekrom-ex-battle-strength-deck'},
+    {'set_name': 'smC: Tapu Bulu-GX Enhanced Starter Set',
+     'url_value': 'smc-tapu-bulu-gx-enhanced-starter-set'},
+    {'set_name': 'Gift Box (Latias)', 'url_value': 'gift-box-latias'},
+    {'set_name': 'smH: GX Starter Decks', 'url_value': 'smh-gx-starter-decks'},
+    {'set_name': 'S8: Fusion Arts', 'url_value': 's8-fusion-arts'},
+    {'set_name': 'SV: Skeledirge ex Terastal Starter Set',
+     'url_value': 'sv-skeledirge-ex-terastal-starter-set'},
+    {'set_name': 'SV1V: Violet ex', 'url_value': 'sv1v-violet-ex'},
+    {'set_name': 'BW4: Dark Rush', 'url_value': 'bw4-dark-rush'},
+    {'set_name': 'm1S: Mega Symphonia', 'url_value': 'm1s-mega-symphonia'},
+    {'set_name': 'SV5K: Wild Force', 'url_value': 'sv5k-wild-force'},
+    {'set_name': 'BW8: Thunder Knuckle', 'url_value': 'bw8-thunder-knuckle'},
+    {'set_name': 'Champion Road', 'url_value': 'champion-road'},
+    {'set_name': 'XY5-Bt: Tidal Storm', 'url_value': 'xy5-bt-tidal-storm'},
+    {'set_name': 'World Champions Pack', 'url_value': 'world-champions-pack'},
+    {'set_name': 'Typhlosion Constructed Starter Deck',
+     'url_value': 'typhlosion-constructed-starter-deck'},
+    {'set_name': "SV: ex Starter Set Steven's Beldum & Metagross ex",
+     'url_value': 'sv-ex-starter-set-stevens-beldum-and-metagross-ex'},
+    {'set_name': 'Magma Deck Kit', 'url_value': 'magma-deck-kit'},
+    {'set_name': 'SV: Ancient Koraidon ex Starter Deck & Build Set',
+     'url_value': 'sv-ancient-koraidon-ex-starter-deck-and-build-set'},
+    {'set_name': 'SV: Future Miraidon ex Starter Deck & Build Set',
+     'url_value': 'sv-future-miraidon-ex-starter-deck-and-build-set'},
+    {'set_name': 'BW6: Freeze Bolt', 'url_value': 'bw6-freeze-bolt'},
+    {'set_name': 'SV7a: Paradise Dragona', 'url_value': 'sv7a-paradise-dragona'},
+    {'set_name': 'Master Kit (Side Deck)', 'url_value': 'master-kit-side-deck'},
+    {'set_name': 'SV: ex Start Decks', 'url_value': 'sv-ex-start-decks'},
+    {'set_name': 'SV1S: Scarlet ex', 'url_value': 'sv1s-scarlet-ex'},
+    {'set_name': 'Holon Research Tower Lightning Quarter Deck',
+     'url_value': 'holon-research-tower-lightning-quarter-deck'},
+    {'set_name': 'Pt3: Beat of the Frontier', 'url_value': 'pt3-beat-of-the-frontier'},
+    {'set_name': 'DP2: Secret of the Lakes', 'url_value': 'dp2-secret-of-the-lakes'},
+    {'set_name': 'Trainer Prize Cards', 'url_value': 'trainer-prize-cards'},
+    {'set_name': 'Rocket Gang Strikes Back', 'url_value': 'rocket-gang-strikes-back'},
+    {'set_name': 'Pokemon Web', 'url_value': 'pokemon-web'},
+    {'set_name': 's0: Charizard VSTAR vs Rayquaza VMAX Special Deck Set',
+     'url_value': 's0-charizard-vstar-vs-rayquaza-vmax-special-deck-set'},
+    {'set_name': 'SS: Inteleon VMAX High-Class Deck', 'url_value': 'ss-inteleon-vmax-high-class-deck'},
+    {'set_name': 'SV2a: Pokemon Card 151', 'url_value': 'sv2a-pokemon-card-151'},
+    {'set_name': 'XY8-Br: Red Flash', 'url_value': 'xy8-br-red-flash'},
+    {'set_name': 'The Town on No Map', 'url_value': 'the-town-on-no-map'},
+    {'set_name': 'Infernape vs Gallade SP Deck Kit (Gallade)',
+     'url_value': 'infernape-vs-gallade-sp-deck-kit-gallade'},
+    {'set_name': 'sK: VSTAR Premium Trainer Box', 'url_value': 'sk-vstar-premium-trainer-box'},
+    {'set_name': 'sp2: VMAX Special Set', 'url_value': 'sp2-vmax-special-set'},
+    {'set_name': 'SM9: Tag Bolt', 'url_value': 'sm9-tag-bolt'},
+    {'set_name': 'sm1+: Enhanced Expansion Pack Sun & Moon',
+     'url_value': 'sm1plus-enhanced-expansion-pack-sun-and-moon'},
+    {'set_name': 'smK: Trainer Battle Decks', 'url_value': 'smk-trainer-battle-decks'},
+    {'set_name': 'Melee! Pokemon Scramble', 'url_value': 'melee-pokemon-scramble'},
+    {'set_name': 'BREAK Starter Pack', 'url_value': 'break-starter-pack'},
+    {'set_name': 'XY2: Wild Blaze', 'url_value': 'xy2-wild-blaze'},
+    {'set_name': 'SV: ex Starter Set Quaxly & Mimikyu ex',
+     'url_value': 'sv-ex-starter-set-quaxly-and-mimikyu-ex'},
+    {'set_name': 'M2: Inferno X', 'url_value': 'm2-inferno-x'},
+    {'set_name': 'SM5+: Ultra Force', 'url_value': 'sm5plus-ultra-force'},
+    {'set_name': 'L1: SoulSilver Collection', 'url_value': 'l1-soulsilver-collection'},
+    {'set_name': 'Vending Machine cards Series 1 (Blue)',
+     'url_value': 'vending-machine-cards-series-1-blue'},
+    {'set_name': 'Gift Box Mew - Lucario (Crawdaunt Quarter Deck)',
+     'url_value': 'gift-box-mew-lucario-crawdaunt-quarter-deck'},
+    {'set_name': 'Pokemon TCG Classic: Blastoise', 'url_value': 'pokemon-tcg-classic-blastoise'},
+    {'set_name': 'sN: Start Deck 100 CoroCoro Comic Version',
+     'url_value': 'sn-start-deck-100-corocoro-comic-version'},
+    {'set_name': 'SS: Silver Lance & Jet-Black Spirit Jumbo Pack Set',
+     'url_value': 'ss-silver-lance-and-jet-black-spirit-jumbo-pack-set'},
+    {'set_name': 'ADV-P Promotional cards', 'url_value': 'adv-p-promotional-cards'},
+    {'set_name': 'BK: Terrakion Battle Strength Deck',
+     'url_value': 'bk-terrakion-battle-strength-deck'},
+    {'set_name': "Earth's Groudon ex Constructed Starter Deck",
+     'url_value': 'earths-groudon-ex-constructed-starter-deck'},
+    {'set_name': 'Holon Research Tower Fire Quarter Deck',
+     'url_value': 'holon-research-tower-fire-quarter-deck'},
+    {'set_name': 'Expansion Pack (No Rarity)', 'url_value': 'expansion-pack-no-rarity'},
+    {'set_name': 'M Master Deck Build Box Power Style',
+     'url_value': 'm-master-deck-build-box-power-style'},
+    {'set_name': 'ADV Expansion Pack', 'url_value': 'adv-expansion-pack'},
+    {'set_name': 'Salamence Constructed Starter Deck',
+     'url_value': 'salamence-constructed-starter-deck'},
+    {'set_name': 'S9a: Battle Region', 'url_value': 's9a-battle-region'},
+    {'set_name': 'Pokemon TCG Classic: Charizard', 'url_value': 'pokemon-tcg-classic-charizard'},
+    {'set_name': 'SV3: Ruler of the Black Flame', 'url_value': 'sv3-ruler-of-the-black-flame'},
+    {'set_name': 'Pokemon TCG Classic: Venusaur', 'url_value': 'pokemon-tcg-classic-venusaur'},
+    {'set_name': 'S1H: Shield', 'url_value': 's1h-shield'},
+    {'set_name': "Pt1: Galactic's Conquest", 'url_value': 'pt1-galactics-conquest'},
+    {'set_name': 'SM2L: Alolan Moonlight', 'url_value': 'sm2l-alolan-moonlight'},
+    {'set_name': 'Pt4: Advent of Arceus', 'url_value': 'pt4-advent-of-arceus'},
+    {'set_name': 'SV2D: Clay Burst', 'url_value': 'sv2d-clay-burst'},
+    {'set_name': 'SV: Stellar Miracle Deck Build Box',
+     'url_value': 'sv-stellar-miracle-deck-build-box'},
+    {'set_name': 'Battle Academy', 'url_value': 'battle-academy'},
+    {'set_name': 'sp6: VSTAR Special Set', 'url_value': 'sp6-vstar-special-set'},
+    {'set_name': 'City Gym Decks', 'url_value': 'city-gym-decks'},
+    {'set_name': 'DPt Gift Box (Pikachu)', 'url_value': 'dpt-gift-box-pikachu'},
+    {'set_name': 'Clash of the Blue Sky', 'url_value': 'clash-of-the-blue-sky'},
+    {'set_name': 'Miracle of the Desert', 'url_value': 'miracle-of-the-desert'},
+    {'set_name': 'SM11: Miracle Twin', 'url_value': 'sm11-miracle-twin'},
+    {'set_name': 'smD: Ash vs Team Rocket Deck Kit', 'url_value': 'smd-ash-vs-team-rocket-deck-kit'},
+    {'set_name': 'BW9: Megalo Cannon', 'url_value': 'bw9-megalo-cannon'},
+    {'set_name': 'sC: Grimmsnarl Starter Set VMAX', 'url_value': 'sc-grimmsnarl-starter-set-vmax'},
+    {'set_name': 'Garchomp vs Charizard SP Deck Kit (Charizard)',
+     'url_value': 'garchomp-vs-charizard-sp-deck-kit-charizard'},
+    {'set_name': 'Gift Box Mew - Lucario (Mightyena Quarter Deck)',
+     'url_value': 'gift-box-mew-lucario-mightyena-quarter-deck'},
+    {'set_name': 'Torchic Constructed Starter Deck', 'url_value': 'torchic-constructed-starter-deck'},
+    {'set_name': 'S3: Infinity Zone', 'url_value': 's3-infinity-zone'},
+    {'set_name': 'Intro Pack Neo (Totodile)', 'url_value': 'intro-pack-neo-totodile'},
+    {'set_name': 'PtS: Shaymin LV.X Collection Pack', 'url_value': 'pts-shaymin-lvx-collection-pack'},
+    {'set_name': 'smI: Flareon-GX, Vaporeon-GX & Jolteon-GX Starter Sets',
+     'url_value': 'smi-flareon-gx-vaporeon-gx-and-jolteon-gx-starter-sets'},
+    {'set_name': 'CP6: Expansion Pack 20th Anniversary',
+     'url_value': 'cp6-expansion-pack-20th-anniversary'},
+    {'set_name': 'S9: Star Birth', 'url_value': 's9-star-birth'},
+    {'set_name': 'DPt Gift Box (Piplup)', 'url_value': 'dpt-gift-box-piplup'},
+    {'set_name': 'sp4: Eevee Heroes VMAX Special Set',
+     'url_value': 'sp4-eevee-heroes-vmax-special-set'},
+    {'set_name': 'XY10: Awakening Psychic King', 'url_value': 'xy10-awakening-psychic-king'},
+    {'set_name': 'Pokemon VS', 'url_value': 'pokemon-vs'},
+    {'set_name': 'Pokemon-e Starter Deck', 'url_value': 'pokemon-e-starter-deck'},
+    {'set_name': 'Neo Premium File 3', 'url_value': 'neo-premium-file-3'},
+    {'set_name': 'Entry Pack', 'url_value': 'entry-pack'},
+    {'set_name': 'Giratina vs Dialga Deck Kit (Giratina)',
+     'url_value': 'giratina-vs-dialga-deck-kit-giratina'},
+    {'set_name': 'MBG: MEGA Starter Set Mega Gengar ex',
+     'url_value': 'mbg-mega-starter-set-mega-gengar-ex'},
+    {'set_name': 'Yveltal Half Deck', 'url_value': 'yveltal-half-deck'},
+    {'set_name': 'Palkia LV.X Constructed Standard Deck',
+     'url_value': 'palkia-lvx-constructed-standard-deck'},
+    {'set_name': 'Intro Pack (Bulbasaur)', 'url_value': 'intro-pack-bulbasaur'},
+    {'set_name': 'Emerald Gift Box (Rayquaza)', 'url_value': 'emerald-gift-box-rayquaza'},
+    {'set_name': 'Magma VS Aqua: Two Ambitions', 'url_value': 'magma-vs-aqua-two-ambitions'},
+    {'set_name': 'Mudkip Constructed Starter Deck', 'url_value': 'mudkip-constructed-starter-deck'},
+    {'set_name': 'XY7: Bandit Ring', 'url_value': 'xy7-bandit-ring'},
+    {'set_name': 'XY9: Rage of the Broken Heavens', 'url_value': 'xy9-rage-of-the-broken-heavens'},
+    {'set_name': 'Entry Pack DPt (Giratina)', 'url_value': 'entry-pack-dpt-giratina'},
+    {'set_name': 'SV: Ruler of the Black Flame Deck Build Box',
+     'url_value': 'sv-ruler-of-the-black-flame-deck-build-box'},
+    {'set_name': 'Rulers of the Heavens', 'url_value': 'rulers-of-the-heavens'},
+    {'set_name': 'Fire Quick Construction Pack', 'url_value': 'fire-quick-construction-pack'},
+    {'set_name': 'sPZ: Zeraora VSTAR & VMAX High-Class Deck',
+     'url_value': 'spz-zeraora-vstar-and-vmax-high-class-deck'},
+    {'set_name': 'smB: Premium Trainer Box', 'url_value': 'smb-premium-trainer-box'},
+    {'set_name': 'XYD: M Rayquaza-EX Mega Battle Deck',
+     'url_value': 'xyd-m-rayquaza-ex-mega-battle-deck'},
+    {'set_name': 'S6K: Jet-Black Spirit', 'url_value': 's6k-jet-black-spirit'},
+    {'set_name': 'sPD: Deoxys VSTAR & VMAX High-Class Deck',
+     'url_value': 'spd-deoxys-vstar-and-vmax-high-class-deck'},
+    {'set_name': 'S11a: Incandescent Arcana', 'url_value': 's11a-incandescent-arcana'},
+    {'set_name': 'Magmortar vs Electivire Deck Kit', 'url_value': 'magmortar-vs-electivire-deck-kit'},
+    {'set_name': 'Blastoise + Kyurem-EX Combo Deck',
+     'url_value': 'blastoise-plus-kyurem-ex-combo-deck'},
+    {'set_name': 'Movie Commemoration VS Pack: Sky-Splitting Deoxys',
+     'url_value': 'movie-commemoration-vs-pack-sky-splitting-deoxys'},
+    {'set_name': 'Crossing the Ruins...', 'url_value': 'crossing-the-ruins'},
+    {'set_name': 'SM5M: Ultra Moon', 'url_value': 'sm5m-ultra-moon'},
+    {'set_name': 'smM: Tag Team GX Starter Sets', 'url_value': 'smm-tag-team-gx-starter-sets'},
+    {'set_name': 'XY6: Emerald Break', 'url_value': 'xy6-emerald-break'},
+    {'set_name': 'BW8: Spiral Force', 'url_value': 'bw8-spiral-force'},
+    {'set_name': 'Gift Box (Latios)', 'url_value': 'gift-box-latios'},
+    {'set_name': 'Keldeo Battle Strength Deck', 'url_value': 'keldeo-battle-strength-deck'},
+    {'set_name': 'BW6: Cold Flare', 'url_value': 'bw6-cold-flare'},
+    {'set_name': 'smL: Sun & Moon Family Pokemon Card Game',
+     'url_value': 'sml-sun-and-moon-family-pokemon-card-game'},
+    {'set_name': 'SNP: Noivern BREAK Evolution Pack', 'url_value': 'snp-noivern-break-evolution-pack'},
+    {'set_name': 'SM8b: GX Ultra Shiny', 'url_value': 'sm8b-gx-ultra-shiny'},
+    {'set_name': 'L-P: Legends Promos', 'url_value': 'l-p-legends-promos'},
+    {'set_name': 'Battle Starter Deck (Raichu)', 'url_value': 'battle-starter-deck-raichu'},
+    {'set_name': 'SM7: Sky-Splitting Charisma', 'url_value': 'sm7-sky-splitting-charisma'},
+    {'set_name': "Team Plasma's Powered Half Deck", 'url_value': 'team-plasmas-powered-half-deck'},
+    {'set_name': 'CP3: PokeKyun Collection', 'url_value': 'cp3-pokekyun-collection'},
+    {'set_name': 'BK: Virizion Battle Strength Deck', 'url_value': 'bk-virizion-battle-strength-deck'},
+    {'set_name': 'SV9a: Heat Wave Arena', 'url_value': 'sv9a-heat-wave-arena'},
+    {'set_name': 'S10b: Pokemon GO', 'url_value': 's10b-pokemon-go'},
+    {'set_name': 'SM7a: Thunderclap Spark', 'url_value': 'sm7a-thunderclap-spark'},
+    {'set_name': 'World Hobby Fair', 'url_value': 'world-hobby-fair'},
+    {'set_name': 'SM4A: Ultradimensional Beasts', 'url_value': 'sm4a-ultradimensional-beasts'},
+    {'set_name': 'sp5: V-UNION Special Card Sets', 'url_value': 'sp5-v-union-special-card-sets'},
+    {'set_name': 'SV4M: Future Flash', 'url_value': 'sv4m-future-flash'},
+    {'set_name': 'Miracle Crystal', 'url_value': 'miracle-crystal'},
+    {'set_name': 'SM10: Double Blaze', 'url_value': 'sm10-double-blaze'},
+    {'set_name': 'Elementary School Competition', 'url_value': 'elementary-school-competition'},
+    {'set_name': 'XY4: Phantom Gate', 'url_value': 'xy4-phantom-gate'},
+    {'set_name': 'Vending Machine cards Series 3 (Green)',
+     'url_value': 'vending-machine-cards-series-3-green'},
+    {'set_name': 'SM5S: Ultra Sun', 'url_value': 'sm5s-ultra-sun'},
+    {'set_name': 'L2: Tyranitar Constructed Standard Deck',
+     'url_value': 'l2-tyranitar-constructed-standard-deck'},
+    {'set_name': 'Shiny Collection', 'url_value': 'shiny-collection'},
+    {'set_name': 'Imprison! Gardevoir ex Constructed Standard Deck',
+     'url_value': 'imprison-gardevoir-ex-constructed-standard-deck'},
+    {'set_name': 'DP4: Dawn Dash', 'url_value': 'dp4-dawn-dash'},
+    {'set_name': 'Flygon Constructed Starter Deck', 'url_value': 'flygon-constructed-starter-deck'},
+    {'set_name': 'SM3N: Darkness that Consumes Light',
+     'url_value': 'sm3n-darkness-that-consumes-light'},
+    {'set_name': 'Entry Pack DPt (Palkia)', 'url_value': 'entry-pack-dpt-palkia'},
+    {'set_name': 'P Promotional cards', 'url_value': 'p-promotional-cards'},
+    {'set_name': 'SM1M: Collection Moon', 'url_value': 'sm1m-collection-moon'},
+    {'set_name': 'BW3: Psycho Drive', 'url_value': 'bw3-psycho-drive'},
+    {'set_name': 'SV: Chien-Pao ex Battle Master Deck',
+     'url_value': 'sv-chien-pao-ex-battle-master-deck'},
+    {'set_name': 'Bastiodon the Defender Half Deck', 'url_value': 'bastiodon-the-defender-half-deck'},
+    {'set_name': 'sp1: Zacian + Zamazenta Box', 'url_value': 'sp1-zacian-plus-zamazenta-box'},
+    {'set_name': 'M-P Promotional Cards', 'url_value': 'm-p-promotional-cards'},
+    {'set_name': 'Aqua Deck Kit', 'url_value': 'aqua-deck-kit'},
+    {'set_name': 'BW: Extra Regulation Box', 'url_value': 'bw-extra-regulation-box'},
+    {'set_name': 'Player Placement Trainer Promos', 'url_value': 'player-placement-trainer-promos'},
+    {'set_name': 'S5R: Rapid Strike Master', 'url_value': 's5r-rapid-strike-master'},
+    {'set_name': "Movie Commemoration VS Pack: Sea's Manaphy",
+     'url_value': 'movie-commemoration-vs-pack-seas-manaphy'},
+    {'set_name': 'smN: Tag Team GX Deck Build Box', 'url_value': 'smn-tag-team-gx-deck-build-box'},
+    {'set_name': 'SV5M: Cyber Judge', 'url_value': 'sv5m-cyber-judge'},
+    {'set_name': 'CoroCoro Promotional Cards', 'url_value': 'corocoro-promotional-cards'},
+    {'set_name': 'XYH: M Audino-EX Mega Battle Deck', 'url_value': 'xyh-m-audino-ex-mega-battle-deck'},
+    {'set_name': 'SM11a: Remix Bout', 'url_value': 'sm11a-remix-bout'},
+    {'set_name': 'SV9: Battle Partners', 'url_value': 'sv9-battle-partners'},
+    {'set_name': 's8a-G: 25th Anniversary Golden Box',
+     'url_value': 's8a-g-25th-anniversary-golden-box'},
+    {'set_name': 'smG: Ultra Sun & Ultra Moon Deck Build Boxes',
+     'url_value': 'smg-ultra-sun-and-ultra-moon-deck-build-boxes'},
+    {'set_name': 'XYE: Emboar-EX vs Togekiss-EX Deck Kit',
+     'url_value': 'xye-emboar-ex-vs-togekiss-ex-deck-kit'},
+    {'set_name': 'SM9a: Night Unison', 'url_value': 'sm9a-night-unison'},
+    {'set_name': 'SV1a: Triplet Beat', 'url_value': 'sv1a-triplet-beat'},
+    {'set_name': 'Garchomp vs Charizard SP Deck Kit (Garchomp)',
+     'url_value': 'garchomp-vs-charizard-sp-deck-kit-garchomp'},
+    {'set_name': 'Movie Commemoration Random Pack', 'url_value': 'movie-commemoration-random-pack'},
+    {'set_name': 'XYC: Super Legend Set: Xerneas-EX & Yveltal-EX',
+     'url_value': 'xyc-super-legend-set-xerneas-ex-and-yveltal-ex'},
+    {'set_name': 'Undone Seal', 'url_value': 'undone-seal'},
+    {'set_name': 'SM-P: Sun & Moon Promos', 'url_value': 'sm-p-sun-and-moon-promos'},
+    {'set_name': 'DPt-P Promotional cards', 'url_value': 'dpt-p-promotional-cards'},
+    {'set_name': 'Split Earth', 'url_value': 'split-earth'},
+    {'set_name': 'SV: Sylveon ex Stellar Tera Type Starter Set',
+     'url_value': 'sv-sylveon-ex-stellar-tera-type-starter-set'},
+    {'set_name': 'Battle Gift Set: Thundurus vs Tornadus',
+     'url_value': 'battle-gift-set-thundurus-vs-tornadus'},
+    {'set_name': 'smP1: Rockruff Full Power Deck', 'url_value': 'smp1-rockruff-full-power-deck'},
+    {'set_name': 'sJ: Zacian & Zamazenta vs Eternatus Special Deck Set',
+     'url_value': 'sj-zacian-and-zamazenta-vs-eternatus-special-deck-set'},
+    {'set_name': 'EX Battle Boost', 'url_value': 'ex-battle-boost'},
+    {'set_name': 'Neo Premium File 2', 'url_value': 'neo-premium-file-2'},
+    {'set_name': 'S11: Lost Abyss', 'url_value': 's11-lost-abyss'},
+    {'set_name': 'Mysterious Mountains', 'url_value': 'mysterious-mountains'},
+    {'set_name': 'S12: Paradigm Trigger', 'url_value': 's12-paradigm-trigger'},
+    {'set_name': 'DPt Gift Box (Turtwig)', 'url_value': 'dpt-gift-box-turtwig'},
+    {'set_name': 'S6a: Eevee Heroes', 'url_value': 's6a-eevee-heroes'},
+    {'set_name': 'Hydreigon Half Deck', 'url_value': 'hydreigon-half-deck'},
+    {'set_name': 'Leafeon vs Metagross Expert Deck (Leafeon)',
+     'url_value': 'leafeon-vs-metagross-expert-deck-leafeon'},
+    {'set_name': 'Southern Island', 'url_value': 'southern-island'},
+    {'set_name': 'XY-Bx: Collection X', 'url_value': 'xy-bx-collection-x'},
+    {'set_name': 'Metagross Constructed Starter Deck',
+     'url_value': 'metagross-constructed-starter-deck'},
+    {'set_name': 'PCG-P Promotional cards', 'url_value': 'pcg-p-promotional-cards'},
+    {'set_name': 'Water Quick Construction Pack', 'url_value': 'water-quick-construction-pack'},
+    {'set_name': 'Wind from the Sea', 'url_value': 'wind-from-the-sea'},
+    {'set_name': "Movie Commemoration VS Pack: Aura's Lucario",
+     'url_value': 'movie-commemoration-vs-pack-auras-lucario'},
+    {'set_name': 'PPP Promotional cards', 'url_value': 'ppp-promotional-cards'},
+    {'set_name': 'DP5: Temple of Anger', 'url_value': 'dp5-temple-of-anger'},
+    {'set_name': 'S7R: Blue Sky Stream', 'url_value': 's7r-blue-sky-stream'},
+    {'set_name': 'SV7: Stellar Miracle', 'url_value': 'sv7-stellar-miracle'},
+    {'set_name': 'XY3: Rising Fist', 'url_value': 'xy3-rising-fist'},
+    {'set_name': 'Silver Deck Kit', 'url_value': 'silver-deck-kit'},
+    {'set_name': 'Deoxys Constructed Starter Deck', 'url_value': 'deoxys-constructed-starter-deck'},
+    {'set_name': 'Leafeon vs Metagross Expert Deck (Metagross)',
+     'url_value': 'leafeon-vs-metagross-expert-deck-metagross'},
+    {'set_name': 'SV5a: Crimson Haze', 'url_value': 'sv5a-crimson-haze'},
+    {'set_name': 'sD: V Starter Decks', 'url_value': 'sd-v-starter-decks'},
+    {'set_name': 'SV10: The Glory of Team Rocket', 'url_value': 'sv10-the-glory-of-team-rocket'},
+    {'set_name': 'S8a: 25th Anniversary Collection', 'url_value': 's8a-25th-anniversary-collection'},
+    {'set_name': 'Gift Box Mew - Lucario (Mew Quarter Deck)',
+     'url_value': 'gift-box-mew-lucario-mew-quarter-deck'},
+    {'set_name': 'SI: Start Deck 100', 'url_value': 'si-start-deck-100'},
+    {'set_name': 'SV6a: Night Wanderer', 'url_value': 'sv6a-night-wanderer'},
+    {'set_name': 'Giratina vs Dialga Deck Kit (Dialga)',
+     'url_value': 'giratina-vs-dialga-deck-kit-dialga'},
+    {'set_name': 'sEF: Venusaur Starter Set VMAX', 'url_value': 'sef-venusaur-starter-set-vmax'},
+    {'set_name': 'sF: Single Strike & Rapid Strike Premium Trainer Boxes',
+     'url_value': 'sf-single-strike-and-rapid-strike-premium-trainer-boxes'},
+    {'set_name': 'Scarlet & Violet Energies', 'url_value': 'scarlet-and-violet-energies'},
+    {'set_name': 'SM4+: GX Battle Boost', 'url_value': 'sm4plus-gx-battle-boost'},
+    {'set_name': 'sEK: Blastoise Starter Set VMAX', 'url_value': 'sek-blastoise-starter-set-vmax'},
+    {'set_name': 'XYF: Golduck BREAK + Palkia-EX Combo Deck',
+     'url_value': 'xyf-golduck-break-plus-palkia-ex-combo-deck'},
+    {'set_name': 'L2: Revival Legends', 'url_value': 'l2-revival-legends'},
+    {'set_name': 'XY-P: XY Promos', 'url_value': 'xy-p-xy-promos'},
+    {'set_name': 'Feraligatr Constructed Starter Deck',
+     'url_value': 'feraligatr-constructed-starter-deck'},
+    {'set_name': 'SM3H: To Have Seen the Battle Rainbow',
+     'url_value': 'sm3h-to-have-seen-the-battle-rainbow'},
+    {'set_name': 'Garchomp Half Deck', 'url_value': 'garchomp-half-deck'},
+    {'set_name': 'MBD: MEGA Starter Set Mega Diancie ex',
+     'url_value': 'mbd-mega-starter-set-mega-diancie-ex'},
+    {'set_name': 'Shockwave! Tyranitar ex Constructed Standard Deck',
+     'url_value': 'shockwave-tyranitar-ex-constructed-standard-deck'}
+]
+
+# ----------------------------------------------------------------------------------------------------------------------
+
+SET_US_NAME_LIST = [
+    {'set_name': 'Crown Zenith', 'url_value': 'crown-zenith'},
+    {'set_name': "McDonald's Promos 2016", 'url_value': 'mcdonalds-promos-2016'},
+    {'set_name': 'Sandstorm', 'url_value': 'sandstorm'},
+    {'set_name': 'XY - Steam Siege', 'url_value': 'xy-steam-siege'},
+    {'set_name': 'Base Set', 'url_value': 'base-set'},
+    {'set_name': 'Base Set 2', 'url_value': 'base-set-2'},
+    {'set_name': 'Base Set (Shadowless)', 'url_value': 'base-set-shadowless'},
+    {'set_name': 'Platinum', 'url_value': 'platinum'},
+    {'set_name': 'SV10: Destined Rivals', 'url_value': 'sv10-destined-rivals'},
+    {'set_name': 'Battle Academy 2022', 'url_value': 'battle-academy-2022'},
+    {'set_name': 'Aquapolis', 'url_value': 'aquapolis'},
+    {'set_name': 'XY Trainer Kit: Bisharp & Wigglytuff',
+     'url_value': 'xy-trainer-kit-bisharp-and-wigglytuff'},
+    {'set_name': 'SM - Ultra Prism', 'url_value': 'sm-ultra-prism'},
+    {'set_name': 'MEE: Mega Evolution Energies', 'url_value': 'mee-mega-evolution-energies'},
+    {'set_name': 'Power Keepers', 'url_value': 'power-keepers'},
+    {'set_name': 'Team Rocket Returns', 'url_value': 'team-rocket-returns'},
+    {'set_name': 'SV: Prismatic Evolutions', 'url_value': 'sv-prismatic-evolutions'},
+    {'set_name': 'SM Base Set', 'url_value': 'sm-base-set'},
+    {'set_name': 'XY - Flashfire', 'url_value': 'xy-flashfire'},
+    {'set_name': 'Deoxys', 'url_value': 'deoxys'},
+    {'set_name': 'Pokemon GO', 'url_value': 'pokemon-go'},
+    {'set_name': 'HGSS Trainer Kit: Gyarados & Raichu',
+     'url_value': 'hgss-trainer-kit-gyarados-and-raichu'},
+    {'set_name': 'First Partner Pack', 'url_value': 'first-partner-pack'},
+    {'set_name': 'SWSH11: Lost Origin', 'url_value': 'swsh11-lost-origin'},
+    {'set_name': 'SWSH01: Sword & Shield Base Set', 'url_value': 'swsh01-sword-and-shield-base-set'},
+    {'set_name': 'Professor Program Promos', 'url_value': 'professor-program-promos'},
+    {'set_name': 'XY - Furious Fists', 'url_value': 'xy-furious-fists'},
+    {'set_name': "Champion's Path", 'url_value': 'champions-path'},
+    {'set_name': 'World Championship Decks', 'url_value': 'world-championship-decks'},
+    {'set_name': 'SV: Paldean Fates', 'url_value': 'sv-paldean-fates'},
+    {'set_name': 'Ash vs Team Rocket Deck Kit (JP Exclusive)',
+     'url_value': 'ash-vs-team-rocket-deck-kit-jp-exclusive'},
+    {'set_name': 'SV01: Scarlet & Violet Base Set', 'url_value': 'sv01-scarlet-and-violet-base-set'},
+    {'set_name': "McDonald's Promos 2023", 'url_value': 'mcdonalds-promos-2023'},
+    {'set_name': 'Diamond and Pearl', 'url_value': 'diamond-and-pearl'},
+    {'set_name': 'Stormfront', 'url_value': 'stormfront'},
+    {'set_name': 'SM - Guardians Rising', 'url_value': 'sm-guardians-rising'},
+    {'set_name': 'HeartGold SoulSilver', 'url_value': 'heartgold-soulsilver'},
+    {'set_name': 'Southern Islands', 'url_value': 'southern-islands'},
+    {'set_name': 'Neo Revelation', 'url_value': 'neo-revelation'},
+    {'set_name': 'Team Magma vs Team Aqua', 'url_value': 'team-magma-vs-team-aqua'},
+    {'set_name': 'SWSH05: Battle Styles', 'url_value': 'swsh05-battle-styles'},
+    {'set_name': 'Shining Fates: Shiny Vault', 'url_value': 'shining-fates-shiny-vault'},
+    {'set_name': 'SM - Crimson Invasion', 'url_value': 'sm-crimson-invasion'},
+    {'set_name': 'POP Series 2', 'url_value': 'pop-series-2'},
+    {'set_name': 'SV07: Stellar Crown', 'url_value': 'sv07-stellar-crown'},
+    {'set_name': 'Mysterious Treasures', 'url_value': 'mysterious-treasures'},
+    {'set_name': 'SWSH07: Evolving Skies', 'url_value': 'swsh07-evolving-skies'},
+    {'set_name': 'Dragon Majesty', 'url_value': 'dragon-majesty'},
+    {'set_name': 'Kalos Starter Set', 'url_value': 'kalos-starter-set'},
+    {'set_name': 'SV06: Twilight Masquerade', 'url_value': 'sv06-twilight-masquerade'},
+    {'set_name': 'Ruby and Sapphire', 'url_value': 'ruby-and-sapphire'},
+    {'set_name': 'Trading Card Game Classic', 'url_value': 'trading-card-game-classic'},
+    {'set_name': 'Fossil', 'url_value': 'fossil'},
+    {'set_name': 'Nintendo Promos', 'url_value': 'nintendo-promos'},
+    {'set_name': 'Crystal Guardians', 'url_value': 'crystal-guardians'},
+    {'set_name': 'POP Series 9', 'url_value': 'pop-series-9'},
+    {'set_name': 'Shining Legends', 'url_value': 'shining-legends'},
+    {'set_name': 'Delta Species', 'url_value': 'delta-species'},
+    {'set_name': 'Alternate Art Promos', 'url_value': 'alternate-art-promos'},
+    {'set_name': 'SWSH10: Astral Radiance Trainer Gallery',
+     'url_value': 'swsh10-astral-radiance-trainer-gallery'},
+    {'set_name': 'Legendary Collection', 'url_value': 'legendary-collection'},
+    {'set_name': 'Supreme Victors', 'url_value': 'supreme-victors'},
+    {'set_name': 'Plasma Blast', 'url_value': 'plasma-blast'},
+    {'set_name': 'HGSS Promos', 'url_value': 'hgss-promos'},
+    {'set_name': 'SV05: Temporal Forces', 'url_value': 'sv05-temporal-forces'},
+    {'set_name': 'XY - Phantom Forces', 'url_value': 'xy-phantom-forces'},
+    {'set_name': 'Detective Pikachu', 'url_value': 'detective-pikachu'},
+    {'set_name': 'Jumbo Cards', 'url_value': 'jumbo-cards'},
+    {'set_name': 'SV: Scarlet & Violet Promo Cards', 'url_value': 'sv-scarlet-and-violet-promo-cards'},
+    {'set_name': 'Unseen Forces', 'url_value': 'unseen-forces'},
+    {'set_name': 'XY Trainer Kit: Sylveon & Noivern',
+     'url_value': 'xy-trainer-kit-sylveon-and-noivern'},
+    {'set_name': 'EX Battle Stadium', 'url_value': 'ex-battle-stadium'},
+    {'set_name': 'SM Trainer Kit: Alolan Sandslash & Alolan Ninetales',
+     'url_value': 'sm-trainer-kit-alolan-sandslash-and-alolan-ninetales'},
+    {'set_name': 'Pikachu World Collection Promos', 'url_value': 'pikachu-world-collection-promos'},
+    {'set_name': 'SM Promos', 'url_value': 'sm-promos'},
+    {'set_name': 'SV09: Journey Together', 'url_value': 'sv09-journey-together'},
+    {'set_name': 'Triumphant', 'url_value': 'triumphant'},
+    {'set_name': 'SM - Team Up', 'url_value': 'sm-team-up'},
+    {'set_name': 'Dragon Vault', 'url_value': 'dragon-vault'},
+    {'set_name': 'Trick or Trade BOOster Bundle', 'url_value': 'trick-or-trade-booster-bundle'},
+    {'set_name': 'Secret Wonders', 'url_value': 'secret-wonders'},
+    {'set_name': 'Hidden Fates: Shiny Vault', 'url_value': 'hidden-fates-shiny-vault'},
+    {'set_name': 'Trick or Trade BOOster Bundle 2023',
+     'url_value': 'trick-or-trade-booster-bundle-2023'},
+    {'set_name': 'Gym Challenge', 'url_value': 'gym-challenge'},
+    {'set_name': 'POP Series 4', 'url_value': 'pop-series-4'},
+    {'set_name': 'League & Championship Cards', 'url_value': 'league-and-championship-cards'},
+    {'set_name': 'SM - Celestial Storm', 'url_value': 'sm-celestial-storm'},
+    {'set_name': 'Generations', 'url_value': 'generations'},
+    {'set_name': 'SVE: Scarlet & Violet Energies', 'url_value': 'sve-scarlet-and-violet-energies'},
+    {'set_name': 'Black and White Promos', 'url_value': 'black-and-white-promos'},
+    {'set_name': 'e-Reader Sample Cards', 'url_value': 'e-reader-sample-cards'},
+    {'set_name': 'SV: Black Bolt', 'url_value': 'sv-black-bolt'},
+    {'set_name': 'SWSH02: Rebel Clash', 'url_value': 'swsh02-rebel-clash'},
+    {'set_name': 'XY - Roaring Skies', 'url_value': 'xy-roaring-skies'},
+    {'set_name': 'Arceus', 'url_value': 'arceus'},
+    {'set_name': "McDonald's Promos 2011", 'url_value': 'mcdonalds-promos-2011'},
+    {'set_name': 'Legendary Treasures: Radiant Collection',
+     'url_value': 'legendary-treasures-radiant-collection'},
+    {'set_name': 'SWSH10: Astral Radiance', 'url_value': 'swsh10-astral-radiance'},
+    {'set_name': 'Dragon Frontiers', 'url_value': 'dragon-frontiers'},
+    {'set_name': 'Deck Exclusives', 'url_value': 'deck-exclusives'},
+    {'set_name': 'Call of Legends', 'url_value': 'call-of-legends'},
+    {'set_name': 'Blister Exclusives', 'url_value': 'blister-exclusives'},
+    {'set_name': 'Hidden Legends', 'url_value': 'hidden-legends'},
+    {'set_name': 'Neo Discovery', 'url_value': 'neo-discovery'},
+    {'set_name': 'Plasma Freeze', 'url_value': 'plasma-freeze'},
+    {'set_name': 'SWSH03: Darkness Ablaze', 'url_value': 'swsh03-darkness-ablaze'},
+    {'set_name': 'Legend Maker', 'url_value': 'legend-maker'},
+    {'set_name': 'Battle Academy 2024', 'url_value': 'battle-academy-2024'},
+    {'set_name': 'Kids WB Promos', 'url_value': 'kids-wb-promos'},
+    {'set_name': 'ME: Mega Evolution Promo', 'url_value': 'me-mega-evolution-promo'},
+    {'set_name': 'Legends Awakened', 'url_value': 'legends-awakened'},
+    {'set_name': 'Celebrations', 'url_value': 'celebrations'},
+    {'set_name': 'Black and White', 'url_value': 'black-and-white'},
+    {'set_name': 'Diamond and Pearl Promos', 'url_value': 'diamond-and-pearl-promos'},
+    {'set_name': "McDonald's 25th Anniversary Promos",
+     'url_value': 'mcdonalds-25th-anniversary-promos'},
+    {'set_name': 'XY - Primal Clash', 'url_value': 'xy-primal-clash'},
+    {'set_name': 'SM - Burning Shadows', 'url_value': 'sm-burning-shadows'},
+    {'set_name': 'XY Base Set', 'url_value': 'xy-base-set'},
+    {'set_name': 'XY Trainer Kit: Latias & Latios', 'url_value': 'xy-trainer-kit-latias-and-latios'},
+    {'set_name': 'Celebrations: Classic Collection', 'url_value': 'celebrations-classic-collection'},
+    {'set_name': 'Miscellaneous Cards & Products', 'url_value': 'miscellaneous-cards-and-products'},
+    {'set_name': 'Trick or Trade BOOster Bundle 2024',
+     'url_value': 'trick-or-trade-booster-bundle-2024'},
+    {'set_name': 'Hidden Fates', 'url_value': 'hidden-fates'},
+    {'set_name': 'Jungle', 'url_value': 'jungle'},
+    {'set_name': 'POP Series 6', 'url_value': 'pop-series-6'},
+    {'set_name': 'POP Series 3', 'url_value': 'pop-series-3'},
+    {'set_name': 'Emerging Powers', 'url_value': 'emerging-powers'},
+    {'set_name': 'SWSH11: Lost Origin Trainer Gallery',
+     'url_value': 'swsh11-lost-origin-trainer-gallery'},
+    {'set_name': 'Battle Academy', 'url_value': 'battle-academy'},
+    {'set_name': 'DP Trainer Kit: Manaphy & Lucario',
+     'url_value': 'dp-trainer-kit-manaphy-and-lucario'},
+    {'set_name': 'Generations: Radiant Collection', 'url_value': 'generations-radiant-collection'},
+    {'set_name': 'SM Trainer Kit: Lycanroc & Alolan Raichu',
+     'url_value': 'sm-trainer-kit-lycanroc-and-alolan-raichu'},
+    {'set_name': 'Great Encounters', 'url_value': 'great-encounters'},
+    {'set_name': "McDonald's Promos 2024", 'url_value': 'mcdonalds-promos-2024'},
+    {'set_name': 'Undaunted', 'url_value': 'undaunted'},
+    {'set_name': 'SV03: Obsidian Flames', 'url_value': 'sv03-obsidian-flames'},
+    {'set_name': 'SV: Shrouded Fable', 'url_value': 'sv-shrouded-fable'},
+    {'set_name': 'Boundaries Crossed', 'url_value': 'boundaries-crossed'},
+    {'set_name': 'SM - Lost Thunder', 'url_value': 'sm-lost-thunder'},
+    {'set_name': 'Rumble', 'url_value': 'rumble'}, {'set_name': 'Dragon', 'url_value': 'dragon'},
+    {'set_name': 'SWSH09: Brilliant Stars Trainer Gallery',
+     'url_value': 'swsh09-brilliant-stars-trainer-gallery'},
+    {'set_name': "McDonald's Promos 2017", 'url_value': 'mcdonalds-promos-2017'},
+    {'set_name': 'POP Series 1', 'url_value': 'pop-series-1'},
+    {'set_name': 'XY - Evolutions', 'url_value': 'xy-evolutions'},
+    {'set_name': 'EX Trainer Kit 1: Latias & Latios',
+     'url_value': 'ex-trainer-kit-1-latias-and-latios'},
+    {'set_name': 'SWSH: Sword & Shield Promo Cards', 'url_value': 'swsh-sword-and-shield-promo-cards'},
+    {'set_name': 'SV02: Paldea Evolved', 'url_value': 'sv02-paldea-evolved'},
+    {'set_name': 'Burger King Promos', 'url_value': 'burger-king-promos'},
+    {'set_name': 'ME02: Phantasmal Flames', 'url_value': 'me02-phantasmal-flames'},
+    {'set_name': 'SV: White Flare', 'url_value': 'sv-white-flare'},
+    {'set_name': 'Crown Zenith: Galarian Gallery', 'url_value': 'crown-zenith-galarian-gallery'},
+    {'set_name': 'Plasma Storm', 'url_value': 'plasma-storm'},
+    {'set_name': 'Neo Destiny', 'url_value': 'neo-destiny'},
+    {'set_name': 'Gym Heroes', 'url_value': 'gym-heroes'},
+    {'set_name': 'XY Trainer Kit: Pikachu Libre & Suicune',
+     'url_value': 'xy-trainer-kit-pikachu-libre-and-suicune'},
+    {'set_name': 'BW Trainer Kit: Excadrill & Zoroark',
+     'url_value': 'bw-trainer-kit-excadrill-and-zoroark'},
+    {'set_name': 'Skyridge', 'url_value': 'skyridge'},
+    {'set_name': 'SWSH12: Silver Tempest', 'url_value': 'swsh12-silver-tempest'},
+    {'set_name': 'WoTC Promo', 'url_value': 'wotc-promo'},
+    {'set_name': 'Emerald', 'url_value': 'emerald'},
+    {'set_name': "McDonald's Promos 2012", 'url_value': 'mcdonalds-promos-2012'},
+    {'set_name': 'My First Battle', 'url_value': 'my-first-battle'},
+    {'set_name': 'Expedition', 'url_value': 'expedition'},
+    {'set_name': 'Unleashed', 'url_value': 'unleashed'},
+    {'set_name': 'EX Trainer Kit 2: Plusle & Minun', 'url_value': 'ex-trainer-kit-2-plusle-and-minun'},
+    {'set_name': 'XY - Fates Collide', 'url_value': 'xy-fates-collide'},
+    {'set_name': 'SWSH06: Chilling Reign', 'url_value': 'swsh06-chilling-reign'},
+    {'set_name': 'SV: Scarlet & Violet 151', 'url_value': 'sv-scarlet-and-violet-151'},
+    {'set_name': "McDonald's Promos 2015", 'url_value': 'mcdonalds-promos-2015'},
+    {'set_name': 'Rising Rivals', 'url_value': 'rising-rivals'},
+    {'set_name': 'Majestic Dawn', 'url_value': 'majestic-dawn'},
+    {'set_name': 'Shining Fates', 'url_value': 'shining-fates'},
+    {'set_name': 'Next Destinies', 'url_value': 'next-destinies'},
+    {'set_name': 'XY Promos', 'url_value': 'xy-promos'},
+    {'set_name': 'SWSH04: Vivid Voltage', 'url_value': 'swsh04-vivid-voltage'},
+    {'set_name': 'ME01: Mega Evolution', 'url_value': 'me01-mega-evolution'},
+    {'set_name': 'SV08: Surging Sparks', 'url_value': 'sv08-surging-sparks'},
+    {'set_name': 'Player Placement Trainer Promos', 'url_value': 'player-placement-trainer-promos'},
+    {'set_name': 'Holon Phantoms', 'url_value': 'holon-phantoms'},
+    {'set_name': 'Dragons Exalted', 'url_value': 'dragons-exalted'},
+    {'set_name': 'POP Series 7', 'url_value': 'pop-series-7'},
+    {'set_name': 'Best of Promos', 'url_value': 'best-of-promos'},
+    {'set_name': 'Double Crisis', 'url_value': 'double-crisis'},
+    {'set_name': 'XY - BREAKpoint', 'url_value': 'xy-breakpoint'},
+    {'set_name': 'Noble Victories', 'url_value': 'noble-victories'},
+    {'set_name': 'Team Rocket', 'url_value': 'team-rocket'},
+    {'set_name': 'SM - Unbroken Bonds', 'url_value': 'sm-unbroken-bonds'},
+    {'set_name': 'SM - Forbidden Light', 'url_value': 'sm-forbidden-light'},
+    {'set_name': "McDonald's Promos 2018", 'url_value': 'mcdonalds-promos-2018'},
+    {'set_name': 'Prize Pack Series Cards', 'url_value': 'prize-pack-series-cards'},
+    {'set_name': 'XY - BREAKthrough', 'url_value': 'xy-breakthrough'},
+    {'set_name': 'XY - Ancient Origins', 'url_value': 'xy-ancient-origins'},
+    {'set_name': 'SWSH12: Silver Tempest Trainer Gallery',
+     'url_value': 'swsh12-silver-tempest-trainer-gallery'},
+    {'set_name': "McDonald's Promos 2022", 'url_value': 'mcdonalds-promos-2022'},
+    {'set_name': 'POP Series 5', 'url_value': 'pop-series-5'},
+    {'set_name': "McDonald's Promos 2014", 'url_value': 'mcdonalds-promos-2014'},
+    {'set_name': 'SWSH09: Brilliant Stars', 'url_value': 'swsh09-brilliant-stars'},
+    {'set_name': 'POP Series 8', 'url_value': 'pop-series-8'},
+    {'set_name': "McDonald's Promos 2019", 'url_value': 'mcdonalds-promos-2019'},
+    {'set_name': 'Dark Explorers', 'url_value': 'dark-explorers'},
+    {'set_name': 'Neo Genesis', 'url_value': 'neo-genesis'},
+    {'set_name': 'SM - Cosmic Eclipse', 'url_value': 'sm-cosmic-eclipse'},
+    {'set_name': 'Legendary Treasures', 'url_value': 'legendary-treasures'},
+    {'set_name': 'SWSH08: Fusion Strike', 'url_value': 'swsh08-fusion-strike'},
+    {'set_name': 'FireRed & LeafGreen', 'url_value': 'firered-and-leafgreen'},
+    {'set_name': 'Countdown Calendar Promos', 'url_value': 'countdown-calendar-promos'},
+    {'set_name': 'SM - Unified Minds', 'url_value': 'sm-unified-minds'},
+    {'set_name': 'SV04: Paradox Rift', 'url_value': 'sv04-paradox-rift'}
+]

+ 252 - 0
pokemon_tcg_spider/tcg_jp_pokemon_spider.py

@@ -0,0 +1,252 @@
+# -*- coding: utf-8 -*-
+# Author : Charley
+# Python : 3.10.8
+# Date   : 2025/11/26 17:59
+import inspect
+import requests
+import user_agent
+from loguru import logger
+from tenacity import retry, stop_after_attempt, wait_fixed
+from jp_set_name_list import SET_JP_NAME_LIST
+from mysql_pool import MySQLConnectionPool
+
+crawler_language = "tcg jp"
+
+logger.remove()
+logger.add("./logs/{time:YYYYMMDD}.log", encoding='utf-8', rotation="00:00",
+           format="[{time:YYYY-MM-DD HH:mm:ss.SSS}] {level} {message}",
+           level="DEBUG", retention="7 day")
+
+
+def after_log(retry_state):
+    """
+    retry 回调
+    :param retry_state: RetryCallState 对象
+    """
+    # 检查 args 是否存在且不为空
+    if retry_state.args and len(retry_state.args) > 0:
+        log = retry_state.args[0]  # 获取传入的 logger
+    else:
+        log = logger  # 使用全局 logger
+
+    if retry_state.outcome.failed:
+        log.warning(
+            f"Function '{retry_state.fn.__name__}', Attempt {retry_state.attempt_number} Times")
+    else:
+        log.info(f"Function '{retry_state.fn.__name__}', Attempt {retry_state.attempt_number} succeeded")
+
+
+@retry(stop=stop_after_attempt(5), wait=wait_fixed(1), after=after_log)
+def get_proxys(log):
+    """
+    获取代理
+    :return: 代理
+    """
+    tunnel = "x371.kdltps.com:15818"
+    kdl_username = "t13753103189895"
+    kdl_password = "o0yefv6z"
+    try:
+        proxies = {
+            "http": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": kdl_username, "pwd": kdl_password, "proxy": tunnel},
+            "https": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": kdl_username, "pwd": kdl_password, "proxy": tunnel}
+        }
+        return proxies
+    except Exception as e:
+        log.error(f"Error getting proxy: {e}")
+        raise e
+
+
+@retry(stop=stop_after_attempt(5), wait=wait_fixed(1), after=after_log)
+def get_single_page(log, setUrlName, setName, page, sql_pool):
+    """
+    获取单页数据
+    :param log: logger对象
+    :param setUrlName: setUrlName
+    :param setName: setName
+    :param page: 页码
+    :param sql_pool: sql_pool
+    :return: 数据列表长度
+    """
+    log.debug(f"Getting single page: {setUrlName} -> {page}")
+    headers = {
+        "accept": "application/json, text/plain, */*",
+        "content-type": "application/json",
+        "referer": "https://www.tcgplayer.com/",
+        "user-agent": user_agent.generate_user_agent()
+    }
+
+    url = "https://mp-search-api.tcgplayer.com/v1/search/request"
+    params = {
+        "q": "",
+        "isList": "false",
+        # "mpfev": "4528"
+    }
+    data = {
+        "algorithm": "sales_dismax",
+        "from": (page - 1) * 24,
+        "size": 24,
+        "filters": {
+            "term": {
+                "productLineName": [
+                    "pokemon-japan"
+                ],
+                "productTypeName": [
+                    "Cards"
+                ],
+                "setName": [
+                    setUrlName
+                ]
+            },
+            "range": {},
+            "match": {}
+        },
+        "listingSearch": {
+            "context": {
+                "cart": {}
+            },
+            "filters": {
+                "term": {
+                    "sellerStatus": "Live",
+                    "channelId": 0
+                },
+                "range": {
+                    "quantity": {
+                        "gte": 1
+                    }
+                },
+                "exclude": {
+                    "channelExclusion": 0
+                }
+            }
+        },
+        "context": {
+            "cart": {},
+            "shippingCountry": "JP",
+            "userProfile": {}
+        },
+        "settings": {
+            "useFuzzySearch": True,
+            "didYouMean": {}
+        },
+        "sort": {}
+    }
+    response = requests.post(url, headers=headers, params=params, json=data,timeout=22)
+    # print(response.json())
+    response.raise_for_status()
+
+    resp_json = response.json()
+    results = resp_json.get("results", [])
+    if results:
+        # 获取set list
+        # aggregations = results.get("aggregations", {}).get("setName", [])
+        #
+        # info_list = []
+        # for agg in aggregations:
+        #     set_name = agg.get("value")
+        #     url_value = agg.get("urlValue")
+        #     data_dict = {
+        #         "set_name": set_name,
+        #         "url_value": url_value
+        #     }
+        #     info_list.append(data_dict)
+        # print(info_list)
+
+        data_list = results[0].get("results", [])
+        # print(len(data_list))
+
+        info_list = []
+        for data in data_list:
+            card_id = data.get("productId")
+            card_id = int(card_id) if card_id else 0
+            card_name = data.get("productName")
+            pg_value = setUrlName
+            pg_label = setName
+            sales_date = data.get("customAttributes", {}).get("releaseDate")
+            card_no = data.get("customAttributes", {}).get("number")
+            rarity = data.get("rarityName")
+            img = f'https://tcgplayer-cdn.tcgplayer.com/product/{card_id}_in_1000x1000.jpg'
+
+            data_dict = {
+                "card_id": card_id,
+                "card_name": card_name,
+                "img": img,
+                "pg_value": pg_value,
+                "pg_label": pg_label,
+                "sales_date": sales_date,
+                "card_no": card_no,
+                "rarity": rarity,
+                "crawler_language": crawler_language
+            }
+            # print(data_dict)
+            info_list.append(data_dict)
+
+        # 保存数据
+        if info_list:
+            sql_pool.insert_many(table="pokemon_card_record", data_list=info_list, ignore=True)
+
+        return len(data_list)
+    else:
+        log.debug(f"{setName} 第{page}页无数据")
+        return 0
+
+
+def get_list_data(log, setUrlName, setName, sql_pool):
+    """
+    获取列表数据
+    :param log: logger对象
+    :param setUrlName: setUrlName
+    :param setName: setName
+    :param sql_pool: sql_pool
+    """
+    page = 1
+    max_page = 200
+    while page <= max_page:
+        try:
+            len_data_list = get_single_page(log, setUrlName, setName, page, sql_pool)
+        except Exception as e:
+            log.error(f"Error getting single page: {e}")
+            len_data_list = 0
+
+        if len_data_list < 24:
+            log.debug(f"{setName} 第{page}页数据条数:{len_data_list}, break !!!")
+            break
+
+        page += 1
+
+
+@retry(stop=stop_after_attempt(100), wait=wait_fixed(3600), after=after_log)
+def jp_pokemon_main(log):
+    """
+    主函数
+    """
+    log.info(f'开始运行 {inspect.currentframe().f_code.co_name} 爬虫任务.............................................')
+
+    # 配置 MySQL 连接池
+    sql_pool = MySQLConnectionPool(log=log)
+    if not sql_pool.check_pool_health():
+        log.error("数据库连接池异常")
+        raise RuntimeError("数据库连接池异常")
+
+    try:
+        # 获取分类列表
+        log.debug(".......... 获取分类列表 ..........")
+        for d_dict in SET_JP_NAME_LIST:
+            setUrlName = d_dict.get("url_value")
+            setName = d_dict.get("set_name")
+            try:
+                log.info(f"开始获取 {setName} 数据")
+                get_list_data(log, setUrlName, setName, sql_pool)
+            except Exception as e:
+                log.error(f"{inspect.currentframe().f_code.co_name} Request get_list_data error: {e}")
+
+    except Exception as e:
+        log.error(f'{inspect.currentframe().f_code.co_name} error: {e}')
+    finally:
+        log.info(f'爬虫程序 {inspect.currentframe().f_code.co_name} 运行结束,等待下一轮的采集任务............')
+
+
+if __name__ == '__main__':
+    # get_list_data(logger, "si-start-deck-100", "SI: Start Deck 100")
+    # get_list_data(logger, "m2-inferno-x", "M2: Inferno X")
+    # parse_set()
+    jp_pokemon_main(logger)

+ 254 - 0
pokemon_tcg_spider/tcg_us_pokemon_spider.py

@@ -0,0 +1,254 @@
+# -*- coding: utf-8 -*-
+# Author : Charley
+# Python : 3.10.8
+# Date   : 2025/11/26 17:59
+import inspect
+import requests
+import user_agent
+from loguru import logger
+from tenacity import retry, stop_after_attempt, wait_fixed
+from jp_set_name_list import SET_US_NAME_LIST
+from mysql_pool import MySQLConnectionPool
+
+crawler_language = "tcg us"
+
+logger.remove()
+logger.add("./logs/{time:YYYYMMDD}.log", encoding='utf-8', rotation="00:00",
+           format="[{time:YYYY-MM-DD HH:mm:ss.SSS}] {level} {message}",
+           level="DEBUG", retention="7 day")
+
+
+def after_log(retry_state):
+    """
+    retry 回调
+    :param retry_state: RetryCallState 对象
+    """
+    # 检查 args 是否存在且不为空
+    if retry_state.args and len(retry_state.args) > 0:
+        log = retry_state.args[0]  # 获取传入的 logger
+    else:
+        log = logger  # 使用全局 logger
+
+    if retry_state.outcome.failed:
+        log.warning(
+            f"Function '{retry_state.fn.__name__}', Attempt {retry_state.attempt_number} Times")
+    else:
+        log.info(f"Function '{retry_state.fn.__name__}', Attempt {retry_state.attempt_number} succeeded")
+
+
+@retry(stop=stop_after_attempt(5), wait=wait_fixed(1), after=after_log)
+def get_proxys(log):
+    """
+    获取代理
+    :return: 代理
+    """
+    tunnel = "x371.kdltps.com:15818"
+    kdl_username = "t13753103189895"
+    kdl_password = "o0yefv6z"
+    try:
+        proxies = {
+            "http": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": kdl_username, "pwd": kdl_password, "proxy": tunnel},
+            "https": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": kdl_username, "pwd": kdl_password, "proxy": tunnel}
+        }
+        return proxies
+    except Exception as e:
+        log.error(f"Error getting proxy: {e}")
+        raise e
+
+
+@retry(stop=stop_after_attempt(5), wait=wait_fixed(1), after=after_log)
+def get_single_page(log, setUrlName, setName, page, sql_pool):
+    """
+    获取单页数据
+    :param log: logger对象
+    :param setUrlName: setUrlName
+    :param setName: setName
+    :param page: 页码
+    :param sql_pool: sql_pool
+    :return: 数据列表长度
+    """
+    log.debug(f"Getting single page: {setUrlName} -> {page}")
+    headers = {
+        "accept": "application/json, text/plain, */*",
+        "content-type": "application/json",
+        "referer": "https://www.tcgplayer.com/",
+        "user-agent": user_agent.generate_user_agent()
+    }
+
+    url = "https://mp-search-api.tcgplayer.com/v1/search/request"
+    params = {
+        "q": "",
+        "isList": "false",
+        # "mpfev": "4528"
+    }
+    data = {
+        "algorithm": "sales_dismax",
+        "from": (page - 1) * 24,
+        "size": 24,
+        "filters": {
+            "term": {
+                "productLineName": [
+                    "pokemon"
+                ],
+                "productTypeName": [
+                    "Cards"
+                ],
+                "setName": [
+                    setUrlName
+                ]
+            },
+            "range": {},
+            "match": {}
+        },
+        "listingSearch": {
+            "context": {
+                "cart": {},
+                "shippingCountry": "US"
+            },
+            "filters": {
+                "term": {
+                    "sellerStatus": "Live",
+                    "channelId": 0
+                },
+                "range": {
+                    "quantity": {
+                        "gte": 1
+                    }
+                },
+                "exclude": {
+                    "channelExclusion": 0
+                }
+            }
+        },
+        "context": {
+            "cart": {},
+            "shippingCountry": "US",
+            "userProfile": {}
+        },
+        "settings": {
+            "useFuzzySearch": True,
+            "didYouMean": {}
+        },
+        "sort": {}
+    }
+    response = requests.post(url, headers=headers, params=params, json=data)
+    # print(response.json())
+    response.raise_for_status()
+
+    resp_json = response.json()
+    results = resp_json.get("results", [])
+    if results:
+        # # 获取set list
+        # aggregations = results[0].get("aggregations", {}).get("setName", [])
+        #
+        # info_list = []
+        # for agg in aggregations:
+        #     set_name = agg.get("value")
+        #     url_value = agg.get("urlValue")
+        #     data_dict = {
+        #         "set_name": set_name,
+        #         "url_value": url_value
+        #     }
+        #     info_list.append(data_dict)
+        # print(info_list)
+        # time.sleep(11111)
+
+        data_list = results[0].get("results", [])
+        # print(len(data_list))
+
+        info_list = []
+        for data in data_list:
+            card_id = data.get("productId")
+            card_id = int(card_id) if card_id else 0
+            card_name = data.get("productName")
+            pg_value = setUrlName
+            pg_label = setName
+            sales_date = data.get("customAttributes", {}).get("releaseDate")
+            card_no = data.get("customAttributes", {}).get("number")
+            rarity = data.get("rarityName")
+            img = f'https://tcgplayer-cdn.tcgplayer.com/product/{card_id}_in_1000x1000.jpg'
+
+            data_dict = {
+                "card_id": card_id,
+                "card_name": card_name,
+                "img": img,
+                "pg_value": pg_value,
+                "pg_label": pg_label,
+                "sales_date": sales_date,
+                "card_no": card_no,
+                "rarity": rarity,
+                "crawler_language": crawler_language
+            }
+            # print(data_dict)
+            info_list.append(data_dict)
+
+        # 保存数据
+        if info_list:
+            sql_pool.insert_many(table="pokemon_card_record", data_list=info_list, ignore=True)
+
+        return len(data_list)
+    else:
+        log.debug(f"{setName} 第{page}页无数据")
+        return 0
+
+
+def get_list_data(log, setUrlName, setName, sql_pool):
+    """
+    获取列表数据
+    :param log: logger对象
+    :param setUrlName: setUrlName
+    :param setName: setName
+    :param sql_pool: sql_pool
+    """
+    page = 1
+    max_page = 200
+    while page <= max_page:
+        try:
+            len_data_list = get_single_page(log, setUrlName, setName, page, sql_pool)
+        except Exception as e:
+            log.error(f"Error getting single page: {e}")
+            len_data_list = 0
+
+        if len_data_list < 24:
+            log.debug(f"{setName} 第{page}页数据条数:{len_data_list}, break !!!")
+            break
+
+        page += 1
+
+
+@retry(stop=stop_after_attempt(100), wait=wait_fixed(3600), after=after_log)
+def us_pokemon_main(log):
+    """
+    主函数
+    """
+    log.info(f'开始运行 {inspect.currentframe().f_code.co_name} 爬虫任务.............................................')
+
+    # 配置 MySQL 连接池
+    sql_pool = MySQLConnectionPool(log=log)
+    if not sql_pool.check_pool_health():
+        log.error("数据库连接池异常")
+        raise RuntimeError("数据库连接池异常")
+
+    try:
+        # 获取分类列表
+        log.debug(".......... 获取分类列表 ..........")
+        for d_dict in SET_US_NAME_LIST:
+            setUrlName = d_dict.get("url_value")
+            setName = d_dict.get("set_name")
+            try:
+                log.info(f"开始获取 {setName} 数据")
+                get_list_data(log, setUrlName, setName, sql_pool)
+            except Exception as e:
+                log.error(f"{inspect.currentframe().f_code.co_name} Request get_list_data error: {e}")
+
+    except Exception as e:
+        log.error(f'{inspect.currentframe().f_code.co_name} error: {e}')
+    finally:
+        log.info(f'爬虫程序 {inspect.currentframe().f_code.co_name} 运行结束,等待下一轮的采集任务............')
+
+
+if __name__ == '__main__':
+    # get_list_data(logger, "si-start-deck-100", "SI: Start Deck 100")
+    # get_list_data(logger, "m2-inferno-x", "M2: Inferno X")
+    # parse_set()
+    us_pokemon_main(logger)

+ 19 - 0
pokemon_tcg_spider/test.py

@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Author : Charley
+# Python : 3.10.8
+# Date   : 2026/1/4 17:15
+import requests
+import user_agent
+
+headers = {
+    # "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
+    # "accept-language": "en,zh-CN;q=0.9,zh;q=0.8",
+    # "priority": "u=0, i",
+    # "referer": "https://www.pokemon.com/us/pokemon-tcg/pokemon-cards?cardName=&cardText=&evolvesFrom=&rsv10pt5=on&hitPointsMin=0&hitPointsMax=340&retreatCostMin=0&retreatCostMax=5&totalAttackCostMin=0&totalAttackCostMax=5&particularArtist=&advancedSubmit=",
+    "user-agent": user_agent.generate_user_agent()
+}
+
+response = requests.get('https://www.pokemon.com/us/pokemon-tcg/pokemon-cards/series/sv6pt5/41/', headers=headers,
+                        timeout=10)
+print(response.text)
+print(response.status_code)