如何使用代理爬取Google搜索结果

学会如何用住宅代理来刮掉谷歌的SRERP. Python, Node.js,和Go中用于提取有机结果的完整代码示例,以片段为特色,People Assolute data.

如何使用代理爬取Google搜索结果

为什么Scrape谷歌搜索结果?.

Google每天处理超过85亿的搜索,使其搜索引擎结果页(SERPs)成为网上最具价值的竞争智能来源. Scrating Google搜索结果可以让你访问有机排名,特色片段,People Associate Ask boxs,本地包,以及付费的广告投放——都是实时的.

你是否正在建立一个 SERP 监测管道 或者进行一次性关键词研究,程序访问Google结果,可以使工作流程自动化,人工完成需要几个小时. 常用案例包括:

  • 追踪自己在市场上的关键词排名
  • 监测目标查询的竞争者可见度
  • 分析 SERP 特性分发(片段、图像、视频)
  • 建立用于小型和小型企业研究和内容战略的数据集

理解 Google SERP 结构

在写刮片前,需要了解谷歌结果页的解剖学. 现代化的SERP可以包含十几种不同的结果类型:

结果类型CSS / 数据标记说明
有机结果div#search .g有标题、 URL 和片段的标准蓝链接结果
特性片段div.xpdopen在有机结果上方显示的答案框
人们也问div.related-question-pair可扩展的 FAQ 类问题
当地包div.VkpGBb3个当地企业上市地图
知识小组div.kp-wholepage实体信息侧栏
附带结果div.uEierd上下付费搜索广告
Google经常更改类名. 用倒置选择器构建您的解析器, 并定期测试以保持提取的可靠性 。

设置您正在崩溃的环境

要可靠地刮掉Google,您需要三个组件:一个HTTP客户端,一个代理连接,和一个HTML解析器. 以下是Python、Node.js和Go使用的全部示例 代理代词。 。 。

Python 示例

先安装依赖关系 。 那个 代理汉字 Python SDK 简化代理配置。

pip install requests beautifulsoup4
import requests
from bs4 import BeautifulSoup
proxy_url = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
proxies = {
    "http": proxy_url,
    "https": proxy_url,
}
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9",
}
def scrape_google(query, num_results=10):
    params = {
        "q": query,
        "num": num_results,
        "hl": "en",
        "gl": "us",
    }
    response = requests.get(
        "https://www.google.com/search",
        params=params,
        headers=headers,
        proxies=proxies,
        timeout=15,
    )
    response.raise_for_status()
    soup = BeautifulSoup(response.text, "html.parser")
    results = []
    for g in soup.select("div#search .g"):
        title_el = g.select_one("h3")
        link_el = g.select_one("a")
        snippet_el = g.select_one(".VwiC3b")
        if title_el and link_el:
            results.append({
                "title": title_el.get_text(),
                "url": link_el["href"],
                "snippet": snippet_el.get_text() if snippet_el else "",
            })
    return results
results = scrape_google("best residential proxies 2026")
for i, r in enumerate(results, 1):
    print(f"{i}. {r['title']}\n   {r['url']}\n")

节点.js 示例

使用 代理节点 SDK 和问候:

npm install axios cheerio https-proxy-agent
const axios = require('axios');
const cheerio = require('cheerio');
const { HttpsProxyAgent } = require('https-proxy-agent');
const agent = new HttpsProxyAgent('http://USERNAME:PASSWORD@gate.proxyhat.com:8080');
async function scrapeGoogle(query) {
  const { data } = await axios.get('https://www.google.com/search', {
    params: { q: query, num: 10, hl: 'en', gl: 'us' },
    headers: {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
      'Accept-Language': 'en-US,en;q=0.9',
    },
    httpsAgent: agent,
    timeout: 15000,
  });
  const $ = cheerio.load(data);
  const results = [];
  $('div#search .g').each((i, el) => {
    const title = $(el).find('h3').text();
    const url = $(el).find('a').attr('href');
    const snippet = $(el).find('.VwiC3b').text();
    if (title && url) {
      results.push({ position: i + 1, title, url, snippet });
    }
  });
  return results;
}
scrapeGoogle('best residential proxies 2026').then(console.log);

跳转到示例

使用 代理汉特去SDK 和欢乐:

package main
import (
    "fmt"
    "log"
    "net/http"
    "net/url"
    "github.com/PuerkitoBio/goquery"
)
func main() {
    proxyURL, _ := url.Parse("http://USERNAME:PASSWORD@gate.proxyhat.com:8080")
    client := &http.Client{
        Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
    }
    req, _ := http.NewRequest("GET", "https://www.google.com/search?q=best+residential+proxies&num=10&hl=en&gl=us", nil)
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
    req.Header.Set("Accept-Language", "en-US,en;q=0.9")
    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    doc, _ := goquery.NewDocumentFromReader(resp.Body)
    doc.Find("div#search .g").Each(func(i int, s *goquery.Selection) {
        title := s.Find("h3").Text()
        link, _ := s.Find("a").Attr("href")
        fmt.Printf("%d. %s\n   %s\n\n", i+1, title, link)
    })
}

分析不同的 SERP 特性

一个完整的刮刮机应该处理的不仅仅是有机结果。 以下是最有价值的SERP特性的解析图案.

特性片段

# Python: Extract featured snippet
snippet_box = soup.select_one("div.xpdopen")
if snippet_box:
    featured = {
        "type": "featured_snippet",
        "text": snippet_box.get_text(strip=True),
        "source_url": snippet_box.select_one("a")["href"] if snippet_box.select_one("a") else None,
    }

人们也问

# Python: Extract PAA questions
paa_questions = []
for q in soup.select("div.related-question-pair"):
    question_text = q.select_one("span")
    if question_text:
        paa_questions.append(question_text.get_text(strip=True))

本地包结果

# Python: Extract local pack
local_results = []
for item in soup.select("div.VkpGBb"):
    name = item.select_one(".dbg0pd")
    rating = item.select_one(".yi40Hd")
    local_results.append({
        "name": name.get_text() if name else "",
        "rating": rating.get_text() if rating else "",
    })

处理谷歌块和CAPTCHA

Google积极防御自动刮损. 没有合适的代理基础设施,你将会遇到数十个请求中的街区. 关键的防御机制包括:

  • 限制费率 : 一个IP的过多请求触发了429状态代码
  • CAPTCHA 挑战: Google在怀疑自动化时为reCAPTCHA服务
  • IP 声誉 : Datacenter IP 范围比住宅IP受到更多的审查
  • 浏览器指纹 : 缺少或前后不一致的抬头升起旗帜

关于详细的反侦查战略,见我们关于 刮刮而不受阻反机器人系统如何检测代理。 。 。

建议的代理战略

住宅代理对于持续的谷歌刮刮至关重要. 代理哈特住宅代理 * 为数百万个执行伙伴提供上网服务 190多个地点,使您能够自动旋转IP和地理目标。 密钥配置提示 :

  • 在每个请求中旋转 IP —— 在连续的 Google 查询中永远不要重用相同的 IP
  • 在请求之间2-5秒间添加随机延迟
  • 将您的用户代理匹配到真实的浏览器版本
  • 设定 hlgl 参数与您的代理服务器位置一致

参见 代理数据文档 用于认证设置和会话管理。

建造生产扫描器

从脚本转向生产管道需要重新试验逻辑、结构化输出和监测。 以下是Python刮刀的硬化版本:

import requests
import time
import random
import json
from bs4 import BeautifulSoup
from datetime import datetime
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
]
def scrape_serp(query, location="us", retries=3):
    for attempt in range(retries):
        try:
            headers = {
                "User-Agent": random.choice(USER_AGENTS),
                "Accept-Language": "en-US,en;q=0.9",
                "Accept": "text/html,application/xhtml+xml",
            }
            response = requests.get(
                "https://www.google.com/search",
                params={"q": query, "num": 10, "hl": "en", "gl": location},
                proxies={"http": PROXY_URL, "https": PROXY_URL},
                headers=headers,
                timeout=15,
            )
            if response.status_code == 429:
                wait = (attempt + 1) * 10
                print(f"Rate limited. Waiting {wait}s...")
                time.sleep(wait)
                continue
            response.raise_for_status()
            soup = BeautifulSoup(response.text, "html.parser")
            # Check for CAPTCHA
            if "captcha" in response.text.lower() or soup.select_one("#captcha-form"):
                print(f"CAPTCHA detected. Retrying with new IP...")
                time.sleep(random.uniform(5, 10))
                continue
            return parse_serp(soup, query)
        except requests.RequestException as e:
            print(f"Attempt {attempt + 1} failed: {e}")
            time.sleep(random.uniform(2, 5))
    return None
def parse_serp(soup, query):
    results = {
        "query": query,
        "timestamp": datetime.utcnow().isoformat(),
        "organic": [],
        "featured_snippet": None,
        "paa": [],
    }
    # Organic results
    for i, g in enumerate(soup.select("div#search .g")):
        title_el = g.select_one("h3")
        link_el = g.select_one("a")
        snippet_el = g.select_one(".VwiC3b")
        if title_el and link_el:
            results["organic"].append({
                "position": i + 1,
                "title": title_el.get_text(),
                "url": link_el["href"],
                "snippet": snippet_el.get_text() if snippet_el else "",
            })
    # Featured snippet
    snippet_box = soup.select_one("div.xpdopen")
    if snippet_box:
        results["featured_snippet"] = snippet_box.get_text(strip=True)[:500]
    # People Also Ask
    for q in soup.select("div.related-question-pair span"):
        results["paa"].append(q.get_text(strip=True))
    return results
# Usage: scrape a list of keywords
keywords = ["best residential proxies", "proxy for web scraping", "serp tracking tools"]
all_results = []
for kw in keywords:
    result = scrape_serp(kw)
    if result:
        all_results.append(result)
    time.sleep(random.uniform(3, 7))  # Delay between keywords
# Save to JSON
with open("serp_results.json", "w") as f:
    json.dump(all_results, f, indent=2)

缩放您的 SERP 搜索器

当监控数百或数千个关键词时,单行刮刮的速度太慢. 考虑这些比例办法:

  • 同时提出的请求 : 使用 Ayncio( Python) 、 工人线程( Node.js) 或 goroutines( Go) 并行发送多个请求
  • 基于队列的架构 : 将关键字推入队列( Redis, RabbitMQ)并与多个工人处理
  • 代理池管理 : 代理哈特自动处理旋转, 但根据您的需要配置会话粘度
  • 结果缓存 : 缓存 SERP 数据以避免在时间窗口内重复请求相同的查询

将 " 关于建造可伸缩的刮刮系统的全面指导 " 改为 " 我们 " 。 完整网络擦除代理指南。 。 。

法律和道德考虑

Google的"服务条款"限制自动化访问. 在删除 Google SERP 时,遵循本准则:

  • 尊重率限制和避免压倒Google的服务器
  • 将数据用于合法商业目的(监测小型和小型企业、市场研究)
  • 在不了解适用法律的情况下,不以商业方式重新分配原始的SRERP数据
  • 考虑使用Google的官方API 以满足您的需要
在部署大规模紧急应急救援系统拆解器之前,请务必检查您有关网络拆解和数据收集的当地法律。

准备开始了吗?

通过AI过滤访问148多个国家的5000多万个住宅IP。

查看价格住宅代理
← 返回博客