首页 > 解决方案 > 如何在网页抓取中提取属于相同标签名称的元素?

问题描述

被抓取的网页

我得到错误的输出

所以基本上我试图用标签名称“tr”刮掉每一页上的那些流媒体行。在每一行中,我想在输出中包含多个列。我能够包含几乎所有这些列,但是有两个具有相同的标签名称让我很沮丧。(关于追随者的两列)我尝试了索引它们的方法,只得到奇数或偶数,但结果包含在第二张图片中,效果不佳。这些数字只是不断重复,并没有按照应有的方式下降。那么有什么方法可以将“获得的追随者”列正确地放入输出中?

这是我第一次在这里问,所以我不确定它是否足够。如果需要,我很高兴稍后更新更多信息。

for i in range(30):      # Number of pages plus one 
    url = "https://twitchtracker.com/channels/viewership?page={}&searchbox=Course+Name&searchbox_zip=ZIP&distance=50&price_range=0&course_type=both&has_events=0".format(i)
    headers = {'User-agent': 'Mozilla/5.0'}
    page = requests.get(url, headers=headers)
    soup = BeautifulSoup(page.content)
    
    channels = soup.find_all('tr')
    for idx, channel in enumerate(channels):
        if idx % 2 == 1:    
            idx += 1
        Name = ", ".join([p.get_text(strip=True) for p in channel.find_all('a', attrs={'style': 'color:inherit'})])
        Avg = ", ".join([p.get_text(strip=True) for p in channel.find_all('td', class_ = 'color-viewers')])
        Time = ", ".join([p.get_text(strip=True) for p in channel.find_all('td', class_ = 'color-streamed')])
        All = ", ".join([p.get_text(strip=True) for p in channel.find_all('td', class_ = 'color-viewersMax')])
        HW = ", ".join([p.get_text(strip=True) for p in channel.find_all('td', class_ = 'color-watched')])
        FG = ", ".join([soup.find_all('td', class_ = 'color-followers hidden-sm')[idx].get_text(strip=True)])

标签: pythonweb-scrapingbeautifulsoup

解决方案


也许是另一种方法?##

它用于pandas读取表格,您只需清除广告即可。

我还使用time.sleep()延迟循环并对服务器保持温和。

例子

import requests, time
import pandas as pd
df_list = []
for i in range(30):      # Number of pages plus one 
    url = "https://twitchtracker.com/channels/viewership?page={}&searchbox=Course+Name&searchbox_zip=ZIP&distance=50&price_range=0&course_type=both&has_events=0".format(i)
    headers = {'User-agent': 'Mozilla/5.0'}
    page = requests.get(url, headers=headers)
    df_list.append(pd.read_html(page.text)[0])
    
    time.sleep(1.5)
    
df = pd.concat(df_list).reset_index(drop=True)
df.rename(columns={'Unnamed: 2':'Name'}, inplace=True)
df.drop(df.columns[[0,1]],axis=1,inplace=True)
df[~df.Rank.str.contains(".ads { display:")].to_csv('table.csv', mode='w', index=False)

推荐阅读