You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

爬取vivo官网手机仅获取热门机型,如何实现全型号数据爬取

问题原因

你当前代码只能爬取热门机型的核心原因是:该页面除首屏默认展示的热门机型外,其余分系列机型为动态加载内容,初始requests.get拿到的静态HTML中仅包含热门机型的DOM节点,其余机型节点需要前端触发对应系列标签的点击事件后,才会通过接口异步加载插入页面,因此直接解析首屏HTML无法拿到全量机型链接。

调整思路
  • 不需要引入Selenium等自动化渲染工具,直接调用页面加载机型列表的后端接口即可拿到全量数据
  • 先从首屏HTML中提取所有机型系列的ID,再逐个请求对应系列的机型列表接口,解析拿到所有机型的详情页链接
  • 补充请求头模拟浏览器访问,避免被站点反爬拦截
  • 增加异常捕获,避免单个机型页面结构异常导致整个爬取任务中断
  • 修正原代码中错误的输出文件名(原代码写的是oppophones.csv,实际为vivo机型数据)
调整后可运行代码
import pandas as pd
from bs4 import BeautifulSoup
import requests
import time

# 统一请求头,模拟浏览器访问
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Referer": "https://www.vivo.com/in/support/system-update"
}
baseurl = 'https://www.vivo.com'

def get_all_phone_links():
    all_links = []
    # 先拿首屏内容,获取所有机型系列ID
    r = requests.get('https://www.vivo.com/in/support/system-update', headers=headers)
    sp = BeautifulSoup(r.text, 'lxml')
    # 先提取首屏已加载的热门机型链接
    hot_links = sp.select('li.box-model-item a')
    all_links.extend([baseurl + link.attrs['href'] for link in hot_links])
    
    # 提取所有非热门系列的ID
    series_items = sp.select('.series-item[data-id]')
    series_ids = [item['data-id'] for item in series_items if item['data-id'] != '0'] # 0对应热门机型,已经抓取过
    
    # 逐个系列请求接口拿机型列表
    list_api = 'https://www.vivo.com/in/support/systemUpdate/getPhoneList'
    for sid in series_ids:
        resp = requests.post(list_api, data={"seriesId": sid}, headers=headers)
        if resp.status_code != 200:
            continue
        # 接口返回对应系列的HTML片段,直接解析即可
        series_sp = BeautifulSoup(resp.text, 'lxml')
        series_links = series_sp.select('li.box-model-item a')
        all_links.extend([baseurl + link.attrs['href'] for link in series_links])
        time.sleep(0.5) # 增加短延时,避免请求过于频繁被拦截
    # 链接去重
    return list(set(all_links))


def phone_data(url):
    try:
        r = requests.get(url, headers=headers, timeout=10)
        sp = BeautifulSoup(r.text, 'lxml')
        release_date_tag = sp.select_one('.no-flip-over:-soup-contains("Release date") + span')
        downloads_tag = sp.select_one('.no-flip-over:-soup-contains("Downloads") + span')
        data = {
            "phone_url": url,
            "Release_Date": release_date_tag.text.strip() if release_date_tag else "",
            "Downloads": downloads_tag.text.strip() if downloads_tag else "",
        }
        return data
    except Exception as e:
        print(f"爬取{url}失败: {str(e)}")
        return None


def main():
    urls = get_all_phone_links()
    results = []
    for url in urls:
        res = phone_data(url)
        if res:
            results.append(res)
        time.sleep(0.3)
    return results


if __name__ == "__main__":
    df = pd.DataFrame(main())
    df.to_csv("vivo_phones.csv", index=False)
    print(f"爬取完成,共保存{len(df)}条机型数据,已写入vivo_phones.csv")
注意事项
  • 代码中设置的延时不要随意调小,避免给站点服务器造成过大压力,也防止自身IP被临时封禁
  • 如果后续站点调整了接口路径或者HTML类名,对应更新选择器或者接口地址即可
  • 爬取到的数据请仅用于个人学习用途,遵守站点相关规则

内容的提问来源于stack exchange,提问作者Prathik Thamalla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 05:03:39