如何使用线程池按文本文件每行发送POST请求实现Anilist用户名检测
问题根因
- 你当前使用的多进程逻辑存在设计错误:给进程池传入的迭代参数是无意义的
range(0,5000),而req_split函数每次执行都会全量读取用户名列表、遍历所有用户名发起请求,相当于开多少个进程,所有用户名就会被重复检测多少次 - 多进程场景下全局变量
checked、available不会跨进程共享,当前的计数逻辑完全失效 - 写入可用用户名的代码存在笔误,把整个用户名列表
username写入了文件而不是当前检测的name - 拼接请求URL的时候加了无意义的
str(r),会导致请求地址错误
修正方案
提前一次性读取所有用户名列表,把用户名作为迭代参数传入进程池,每个进程单次只处理1个用户名即可,修正后代码如下:
import requests from multiprocessing import Pool from colorama import Fore # 提前一次性读取所有用户名,避免每个进程重复读 usernameFile = "替换成你自己的用户名字典文件名.txt" with open(f"external/{usernameFile}", "r", encoding="utf-8") as f: username_list = [line.strip() for line in f if line.strip()] checked = 0 available = 0 def req_split(name): data = { "query": "mutation($name:String){CreateUser(userName:$name){id name about avatar{large}bannerImage unreadNotificationCount donatorTier donatorBadge moderatorRoles options{titleLanguage airingNotifications displayAdultContent profileColor notificationOptions{type enabled}}mediaListOptions{scoreFormat rowOrder animeList{customLists sectionOrder splitCompletedSectionByFormat advancedScoring advancedScoringEnabled}mangaList{customLists sectionOrder splitCompletedSectionByFormat advancedScoring advancedScoringEnabled}}}}", "variables": {"name": name} } headers = { "Host": "anilist.co", "schema": "internal", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36", "Content-Type": "application/json" } url = 'https://anilist.co/graphql' # 移除无意义的参数拼接 req = requests.post(url, headers=headers, json=data) if "userName" in req.text: print(f"{Fore.LIGHTBLACK_EX}[+]{Fore.RESET} Taken: {name}") return (name, False) else: print(f"{Fore.LIGHTBLACK_EX}[+]{Fore.RESET} Available: {name}") with open('external/available.txt', "a", encoding="utf-8") as av: av.write(f'{name}\n') return (name, True) if __name__ == "__main__": # 并发数不要开过高,避免被接口限流封IP,建议10~20即可 with Pool(20) as p: # 直接把用户名列表作为参数传入进程池 results = p.imap_unordered(req_split, username_list) for res in results: checked += 1 if res[1]: available += 1 print(f"\n检测完成,共检测{checked}个用户名,可用{available}个")
注意事项
- Windows系统下多进程代码必须放在
if __name__ == "__main__":判断下,否则会运行报错 - 可以额外添加请求异常捕获逻辑,处理超时、网络错误等异常场景,避免个别请求失败导致进程退出
- 如果用户名列表量级很大,建议先批量收集可用用户名后统一写入文件,减少频繁IO的开销
内容的提问来源于stack exchange,提问作者user16246484
相关产品推荐
相关产品推荐

