You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python爬取问题:链接内容变化及requests无法获取特定表格

嘿,我来帮你解决这两个爬虫问题,都是实际爬取中常见的场景,咱们一个个来:

问题1:如何使用Python爬取每个链接对应内容均不同的页面?

这其实是批量爬取里的典型场景,核心就是遍历链接池 + 按需解析每个页面,给你拆解成可落地的步骤:

  • 第一步:整理目标链接列表
    你可以手动把所有需要爬的链接存到一个列表里,或者先爬取一个汇总页面(比如政治人物的列表页),用BeautifulSoup提取所有目标链接的href属性,生成链接池。比如:

    import requests
    from bs4 import BeautifulSoup
    
    # 假设这是汇总页面URL
    list_url = "https://example.com/politicians"
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}
    response = requests.get(list_url, headers=headers)
    soup = BeautifulSoup(response.text, "html.parser")
    # 提取所有政治人物的详情页链接
    link_pool = [a["href"] for a in soup.select("div.politician-item a")]
    
  • 第二步:批量遍历并请求页面
    遍历链接池里的每个链接,逐个发起请求。这里一定要注意反爬措施:加请求头模拟浏览器、设置请求间隔(避免给服务器太大压力)、处理请求异常(比如超时、404)。示例:

    import time
    
    for link in link_pool:
        try:
            # 处理相对链接,拼接成完整URL
            full_link = "https://example.com" + link if not link.startswith("http") else link
            response = requests.get(full_link, headers=headers, timeout=10)
            response.raise_for_status()  # 抛出HTTP错误
            # 这里调用解析函数处理当前页面
            parse_page(response.text)
            time.sleep(1)  # 间隔1秒,可根据情况调整
        except Exception as e:
            print(f"爬取{full_link}失败: {str(e)}")
            continue
    
  • 第三步:按需解析每个页面
    因为每个页面内容不同,你可以根据页面的特征(比如URL包含的关键词、页面里的特定标识)来分支处理解析逻辑。如果是同一类站点的不同详情页,大概率核心内容的标签/class是有规律的,比如提取标题、描述、表格等:

    def parse_page(html):
        soup = BeautifulSoup(html, "html.parser")
        # 提取页面标题
        title = soup.find("h1").get_text(strip=True)
        # 提取特定内容,比如不同页面可能有不同的模块,可根据实际情况调整
        description = soup.find("div", class_="desc").get_text(strip=True) if soup.find("div", class_="desc") else "无描述"
        # 存储数据,比如写入CSV
        with open("politicians_data.csv", "a", encoding="utf-8") as f:
            f.write(f"{title},{description}\n")
    
  • 第四步:数据存储
    把每个页面爬取到的数据统一存储,推荐用CSV、JSON或者SQLite,方便后续分析和查看。


问题2:Python3下爬取动态加载的表格(requests无法获取)

这种情况99%是因为表格内容是JavaScript动态渲染的(比如通过AJAX异步加载、或者前端框架渲染),requests只能拿到静态HTML,自然找不到表格元素。给你两种解决方案,按优先级推荐:

方案1:直接请求数据接口(高效首选)

很多网站的动态表格数据是通过XHR/Fetch请求从后端接口获取的,你可以通过浏览器开发者工具找到这个接口:

  1. 打开目标页面,按F12打开开发者工具,切换到「Network」标签;
  2. 刷新页面,在「XHR」或「Fetch」分类下找返回JSON数据的请求,查看请求URL、参数和响应内容;
  3. 如果找到对应表格的接口,直接用requests请求这个接口,拿到JSON数据后解析成表格即可。

示例代码:

import requests
import json

# 假设找到的接口URL,可能需要携带特定参数(比如政治人物ID)
api_url = "https://example.com/api/politician/assets"
params = {"politician_id": "123"}  # 每个政治人物的ID不同,需要从详情页提取或者遍历
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}

response = requests.get(api_url, params=params, headers=headers)
data = response.json()

# 解析JSON数据,提取"Descrição""Tipo""Valor do Bem"字段
for item in data["assets"]:
    descricao = item.get("descricao")
    tipo = item.get("tipo")
    valor = item.get("valor_do_bem")
    print(f"Descrição: {descricao}, Tipo: {tipo}, Valor: {valor}")

方案2:用无头浏览器渲染页面(适合复杂场景)

如果找不到接口或者接口有加密/反爬,那就用无头浏览器模拟真实浏览器加载页面,等待JS渲染完成后再提取表格。推荐用Playwright(比Selenium更简洁,自带浏览器驱动):

  1. 先安装Playwright:

    pip install playwright
    playwright install chrome
    
  2. 示例代码(针对每个政治人物页面处理):

    from playwright.sync_api import sync_playwright
    import time
    
    def crawl_dynamic_table(url):
        with sync_playwright() as p:
            browser = p.chromium.launch(headless=True)  # headless=True表示无界面模式
            page = browser.new_page(user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
            page.goto(url, wait_until="networkidle")  # 等待网络空闲,确保内容加载完成
            
            # 定位表格,假设表格有特定的class或ID
            table = page.locator("table.assets-table")
            # 遍历表格行,跳过表头
            rows = table.locator("tr").all()[1:]
            for row in rows:
                descricao = row.locator("td:nth-child(1)").text_content().strip()
                tipo = row.locator("td:nth-child(2)").text_content().strip()
                valor = row.locator("td:nth-child(3)").text_content().strip()
                print(f"Descrição: {descricao}, Tipo: {tipo}, Valor: {valor}")
            
            browser.close()
    
    # 遍历每个政治人物的URL
    politician_urls = ["https://example.com/politician/1", "https://example.com/politician/2"]
    for url in politician_urls:
        crawl_dynamic_table(url)
        time.sleep(1)
    

注意:如果用Selenium的话,步骤类似,但需要手动下载对应浏览器的驱动,代码会稍微繁琐一点。


内容的提问来源于stack exchange,提问作者Reinaldo Chaves

火山引擎 最新活动