如何用Python+BeautifulSoup爬取Instagram红人数据并导出Excel
爬取Instagram红人数据解决方案
需求说明
你需要从印度Instagram红人榜单页爬取前1000个账号的username、age、bio、粉丝数、关注数、互动率、平均点赞、平均评论、发帖总数、头像链接、头像文件,最终导出到Excel。
现有代码的核心问题
- 没有添加请求头,容易被站点反爬拦截,导致部分页面返回异常数据
- 只解析了详情页的统计卡片区块,没有提取顶部个人信息区块的age、bio、头像等字段
- 没有处理分页逻辑,只能爬取第一页最多100条数据,无法获取到1000条
- 数据存储结构不规整,不利于后续导出Excel
具体实现方案
1. 前置依赖安装
先安装需要的第三方库:
pip install requests beautifulsoup4 pandas openpyxl
2. 核心逻辑调整
- 所有请求添加
User-Agent请求头,每次请求间隔1-2秒避免被封 - 列表页遍历1-10页获取前1000个红人的详情页链接
- 详情页新增解析顶部个人信息区块,提取缺失的字段
- 统一用字典存储单条账号数据,最后汇总为列表转DataFrame导出Excel
3. 完整代码示例
import time import requests from bs4 import BeautifulSoup import pandas as pd # 配置请求头 HEADERS = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } # 存储所有红人数据的列表 all_data = [] # 遍历1-10页获取前1000条数据 for page in range(1, 11): print(f"正在爬取第{page}页") list_url = f"https://starngage.com/app/global/influencer/ranking/india?page={page}" list_r = requests.get(list_url, headers=HEADERS) list_soup = BeautifulSoup(list_r.text, 'lxml') # 获取当前页所有红人详情链接 table = list_soup.find('table', class_='table table-hover table-responsive-sm') if not table: continue trs = table.find('tbody').find_all('tr') for tr in trs: try: # 列表页提取基础信息 name_td = tr.find_all('td')[2] full_name = name_td.text.strip() username = name_td.find('a').text.replace('@', '').strip() detail_url = name_td.find('a')['href'] # 请求详情页 time.sleep(1.5) detail_r = requests.get(detail_url, headers=HEADERS) detail_soup = BeautifulSoup(detail_r.text, 'lxml') # 提取顶部个人信息 profile_card = detail_soup.find('div', class_='card-body p-4') # 头像链接 avatar_url = profile_card.find('img', class_='rounded-circle img-fluid shadow')['src'] # bio bio = profile_card.find('p', class_='text-muted mt-3 mb-3').text.strip() if profile_card.find('p', class_='text-muted mt-3 mb-3') else '' # age和其他基础信息 info_items = profile_card.find_all('div', class_='d-flex align-items-center mb-2') age = '' for item in info_items: label = item.find('div', class_='text-muted').text.strip() if label == 'Age': age = item.find_all('div')[-1].text.strip() break # 提取统计数据 stat_cards = detail_soup.find('div', class_='row row-cards summary').find_all('div', class_='card-body p-3') stat_dict = {} for card in stat_cards: key = card.find('h6').text.strip() value = card.find_all('div')[-1].text.strip() stat_dict[key] = value # 组装单条数据 celeb_data = { 'full_name': full_name, 'username': username, 'age': age, 'bio': bio, 'follower_count': stat_dict.get('Followers', ''), 'following_count': stat_dict.get('Following', ''), 'engagement_rate': stat_dict.get('Engagement Rate', ''), 'avg_likes': stat_dict.get('Avg. Likes', ''), 'avg_comments': stat_dict.get('Avg. Comments', ''), 'total_posts': stat_dict.get('Posts', ''), 'profile_pic_url': avatar_url } all_data.append(celeb_data) # 如果需要下载头像到本地,提前创建avatars文件夹,放开下面注释即可 # avatar_content = requests.get(avatar_url, headers=HEADERS).content # with open(f'./avatars/{username}.jpg', 'wb') as f: # f.write(avatar_content) except Exception as e: print(f"爬取{username}出错:{e}") continue # 导出到Excel df = pd.DataFrame(all_data) df.to_excel('印度instagram红人数据.xlsx', index=False, engine='openpyxl') print(f"共爬取{len(all_data)}条数据,已导出到Excel")
注意事项
- 可以根据实际情况调整请求间隔时间,若出现被拦截的情况,可以加长间隔或者补充代理逻辑
- 若站点页面结构发生调整,对应的标签选择器需要根据实际页面结构微调
内容的提问来源于stack exchange,提问作者user16470167
相关产品推荐
相关产品推荐

