如何简化MyAnimeList动漫榜单爬取代码中的if条件语句?
问题描述
我想要爬取页面https://myanimelist.net/topanime.php?limit=0中的第1、2、3…页的信息(该网站使用limit=0、50、100…而非page=1、2…实现分页)。当前代码的if与elif块存在大量重复逻辑,请问如何简化这些if语句内的代码?
原代码如下:
data = [] def main(number): driver = webdriver.Chrome() url = 'https://myanimelist.net/topanime.php?limit={}' if number <= 1: driver.get(url.format(0)) soup = BeautifulSoup(driver.page_source, 'html.parser') results = soup.find_all('tr', class_= 'ranking-list') for result in results: Anime = result.find('h3', class_='hoverinfo_trigger fl-l fs14 fw-b anime_ranking_h3').text.replace('\n','') Date = result.find('div', class_='information di-ib mt4').text.replace('\n','') No_eps = result.find('div', class_='information di-ib mt4').text.replace('\n','') Ranking = result.find('td', class_='rank ac').text.replace('\n','') Score = result.find('div', class_='js-top-ranking-score-col di-ib al').text.replace('\n','') data.append({ 'Anime':Anime, 'Date':Date, 'No_eps':No_eps, 'Ranking':Ranking, 'Score':Score }) elif number >= 2: for limit in range(0,(int(number)*50), 50): driver.get(url.format(limit)) soup = BeautifulSoup(driver.page_source, 'html.parser') results = soup.find_all('tr', class_= 'ranking-list') for result in results: Anime = result.find('h3', class_='hoverinfo_trigger fl-l fs14 fw-b anime_ranking_h3').text.replace('\n','') Date = result.find('div', class_='information di-ib mt4').text.replace('\n','') No_eps = result.find('div', class_='information di-ib mt4').text.replace('\n','') Ranking = result.find('td', class_='rank ac').text.replace('\n','') Score = result.find('div', class_='js-top-ranking-score-col di-ib al').text.replace('\n','') data.append({ 'Anime':Anime, 'Date':Date, 'No_eps':No_eps, 'Ranking':Ranking, 'Score':Score })
简化方案
核心思路是抽离重复逻辑为独立函数,同时统一分页处理规则,彻底去掉冗余的分支判断。
1. 抽离单页解析函数
把页面解析、动漫信息提取的逻辑单独封装,避免重复写相同的提取代码:
def parse_anime_page(soup): anime_items = [] results = soup.find_all('tr', class_='ranking-list') for result in results: # 用strip()替代replace('\n',''),更简洁地清理文本中的换行和多余空格 title = result.find('h3', class_='hoverinfo_trigger fl-l fs14 fw-b anime_ranking_h3').text.strip() info_text = result.find('div', class_='information di-ib mt4').text.strip() ranking = result.find('td', class_='rank ac').text.strip() score = result.find('div', class_='js-top-ranking-score-col di-ib al').text.strip() # 保留原代码中Date和No_eps取同一文本的逻辑,后续可拆分info_text获取更精准数据 anime_items.append({ 'Anime': title, 'Date': info_text, 'No_eps': info_text, 'Ranking': ranking, 'Score': score }) return anime_items
2. 统一分页循环逻辑
不管number是1还是更大的值,都用range生成对应的limit序列,循环处理每个页面,彻底去掉if/elif分支:
data = [] def main(number): driver = webdriver.Chrome() url = 'https://myanimelist.net/topanime.php?limit={}' # 生成limit序列:number=1时是[0],number=2时是[0,50],以此类推 limits = range(0, int(number)*50, 50) for limit in limits: driver.get(url.format(limit)) soup = BeautifulSoup(driver.page_source, 'html.parser') # 调用解析函数,将结果合并到全局data列表 data.extend(parse_anime_page(soup)) driver.quit() # 爬取完成后关闭浏览器,避免进程残留
3. 优化说明
- 去掉冗余分支:用
range统一处理分页,逻辑更简洁易维护 - 代码复用:解析逻辑单独封装后,后续修改提取规则只需改动这一个函数
- 文本清理:
strip()比手动替换换行符更健壮,能同时处理空格、制表符等空白字符 - 资源回收:添加
driver.quit()避免浏览器进程后台残留
内容的提问来源于stack exchange,提问作者Gabo Arosemena
相关产品推荐
相关产品推荐

