0

0

如何使用 Python 抓取 Google 搜索结果

DDD

DDD

发布时间:2024-12-02 14:33:01

|

873人浏览过

|

来源于dev.to

转载

抓取 google 搜索可提供基本的 serp 分析、seo 优化和数据收集功能。现代抓取工具使这个过程更快、更可靠。

我们的一位社区成员撰写了此博客,作为对 crawlee 博客的贡献。如果您想向 crawlee 博客贡献此类博客,请通过我们的 discord 频道与我们联系。

在本指南中,我们将使用 crawlee for python 创建一个 google 搜索抓取工具,可以处理结果排名和分页。

我们将创建一个抓取工具:

  • 从搜索结果中提取标题、url 和描述
  • 处理多个搜索查询
  • 追踪排名位置
  • 处理多个结果页面
  • 以结构化格式保存数据

先决条件

  • python 3.7 或更高版本
  • 对 html 和 css 选择器的基本了解
  • 熟悉网络抓取概念
  • crawlee for python v0.4.2 或更高版本

项目设置

  1. 安装 crawlee 所需的依赖项:

    pipx install crawlee[beautifulsoup,curl-impersonate]
    
  2. 使用 crawlee cli 创建一个新项目:

    pipx run crawlee create crawlee-google-search
    
  3. 出现提示时,选择 beautifulsoup 作为您的模板类型。

    立即学习Python免费学习笔记(深入)”;

  4. 导航到项目目录并完成安装:

    cd crawlee-google-search
    poetry install
    

使用 python 开发 google 搜索抓取工具

1. 定义提取数据

首先,让我们定义提取范围。谷歌的搜索结果现在包括地图、名人、公司详细信息、视频、常见问题和许多其他元素。我们将重点分析带有排名的标准搜索结果。

这是我们要提取的内容:

如何使用 Python 抓取 Google 搜索结果

我们来验证一下是否可以从页面的html代码中提取必要的数据,或者是否需要更深入的分析或js渲染。请注意,此验证对 html 标签敏感:

如何使用 Python 抓取 Google 搜索结果

根据从页面获取的数据,所有必要的信息都存在于 html 代码中。因此,我们可以使用beautifulsoup_crawler。

我们将提取的字段:

  • 搜索结果标题
  • 网址
  • 描述文字
  • 排名位置

2.配置爬虫

首先,让我们创建爬虫配置。

我们将使用 curlimpersonatehttpclient 作为带有预设标头的 http_client,并模拟与 chrome 浏览器相关的内容。

我们还将配置 concurrencysettings 来控制抓取攻击性。这对于避免被 google 屏蔽至关重要。

如果您需要更集中地提取数据,请考虑设置proxyconfiguration。

from crawlee.beautifulsoup_crawler import beautifulsoupcrawler
from crawlee.http_clients.curl_impersonate import curlimpersonatehttpclient
from crawlee import concurrencysettings, httpheaders

async def main() -> none:
    concurrency_settings = concurrencysettings(max_concurrency=5, max_tasks_per_minute=200)

    http_client = curlimpersonatehttpclient(impersonate="chrome124124",
                                            headers=httpheaders({"referer": "https://www.google.com/",
                                                     "accept-language": "en",
                                                     "accept-encoding": "gzip, deflate, br, zstd",
                                                     "user-agent": "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/131.0.0.0 safari/537.36"
                                            }))

    crawler = beautifulsoupcrawler(
        max_request_retries=1,
        concurrency_settings=concurrency_settings,
        http_client=http_client,
        max_requests_per_crawl=10,
        max_crawl_depth=5
    )

    await crawler.run(['https://www.google.com/search?q=apify'])

3. 实现数据提取

首先我们来分析一下需要提取的元素的html代码:

如何使用 Python 抓取 Google 搜索结果

百宝箱
百宝箱

百宝箱是支付宝推出的一站式AI原生应用开发平台,无需任何代码基础,只需三步即可完成AI应用的创建与发布。

下载

可读 id 属性和生成 类名和其他属性之间存在明显区别。创建用于数据提取的选择器时,您应该忽略任何生成的属性。即使您已经了解到 google 已经使用特定的生成标签 n 年了,您也不应该依赖它 - 这反映了您编写健壮代码的经验。

现在我们了解了 html 结构,让我们来实现提取。由于我们的爬虫只处理一种类型的页面,因此我们可以使用 router.default_handler 来处理它。在处理程序中,我们将使用 beautifulsoup 迭代每个搜索结果,在保存结果时提取标题、url 和 text_widget 等数据。

@crawler.router.default_handler
async def default_handler(context: beautifulsoupcrawlingcontext) -> none:
    """default request handler."""
    context.log.info(f'processing {context.request} ...')

    for item in context.soup.select("div#search div#rso div[data-hveid][lang]"):
        data = {
            'title': item.select_one("h3").get_text(),
            "url": item.select_one("a").get("href"),
            "text_widget": item.select_one("div[style*='line']").get_text(),
        }
        await context.push_data(data)

4. 处理分页

由于 google 结果取决于搜索请求的 ip 地理位置,因此我们不能依赖链接文本进行分页。我们需要创建一个更复杂的 css 选择器,无论地理位置和语言设置如何,它都可以工作。

max_crawl_depth 参数控制我们的爬虫应该扫描多少页面。一旦我们有了强大的选择器,我们只需获取下一页链接并将其添加到爬虫队列中即可。

要编写更高效的选择器,请学习 css 和 xpath 语法的基础知识。

    await context.enqueue_links(selector="div[role='navigation'] td[role='heading']:last-of-type > a")

5. 将数据导出为csv格式

由于我们希望以方便的表格格式(例如 csv)保存所有搜索结果数据,因此我们可以在运行爬虫后立即添加 export_data 方法调用:

await crawler.export_data_csv("google_search.csv")

6. 完成 google 搜索抓取工具

虽然我们的核心爬虫逻辑有效,但您可能已经注意到我们的结果目前缺乏排名位置信息。为了完成我们的抓取工具,我们需要通过使用请求中的 user_data 在请求之间传递数据来实现正确的排名位置跟踪。

让我们修改脚本来处理多个查询并跟踪搜索结果分析的排名位置。我们还将爬行深度设置为顶级变量。让我们将 router.default_handler 移至 paths.py 以匹配项目结构:

# crawlee-google-search.main

from crawlee.beautifulsoup_crawler import beautifulsoupcrawler, beautifulsoupcrawlingcontext
from crawlee.http_clients.curl_impersonate import curlimpersonatehttpclient
from crawlee import request, concurrencysettings, httpheaders

from .routes import router

queries = ["apify", "crawlee"]

crawl_depth = 2


async def main() -> none:
    """the crawler entry point."""

    concurrency_settings = concurrencysettings(max_concurrency=5, max_tasks_per_minute=200)

    http_client = curlimpersonatehttpclient(impersonate="chrome124124",
                                            headers=httpheaders({"referer": "https://www.google.com/",
                                                     "accept-language": "en",
                                                     "accept-encoding": "gzip, deflate, br, zstd",
                                                     "user-agent": "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/131.0.0.0 safari/537.36"
                                            }))
    crawler = beautifulsoupcrawler(
        request_handler=router,
        max_request_retries=1,
        concurrency_settings=concurrency_settings,
        http_client=http_client,
        max_requests_per_crawl=100,
        max_crawl_depth=crawl_depth
    )

    requests_lists = [request.from_url(f"https://www.google.com/search?q={query}", user_data = {"query": query}) for query in queries]

    await crawler.run(requests_lists)

    await crawler.export_data_csv("google_ranked.csv")

我们还可以修改处理程序以添加 query 和 order_no 字段以及基本错误处理:

# crawlee-google-search.routes

from crawlee.beautifulsoup_crawler import BeautifulSoupCrawlingContext
from crawlee.router import Router

router = Router[BeautifulSoupCrawlingContext]()


@router.default_handler
async def default_handler(context: BeautifulSoupCrawlingContext) -> None:
    """Default request handler."""
    context.log.info(f'Processing {context.request.url} ...')

    order = context.request.user_data.get("last_order", 1)
    query = context.request.user_data.get("query")
    for item in context.soup.select("div#search div#rso div[data-hveid][lang]"):
        try:
            data = {
                "query": query,
                "order_no": order,
                'title': item.select_one("h3").get_text(),
                "url": item.select_one("a").get("href"),
                "text_widget": item.select_one("div[style*='line']").get_text(),
            }
            await context.push_data(data)
            order += 1
        except AttributeError as e:
            context.log.warning(f'Attribute error for query "{query}": {str(e)}')
        except Exception as e:
            context.log.error(f'Unexpected error for query "{query}": {str(e)}')

    await context.enqueue_links(selector="div[role='navigation'] td[role='heading']:last-of-type > a",
                                user_data={"last_order": order, "query": query})

我们就完成了!

我们的 google 搜索抓取工具已准备就绪。我们来看看 google_ranked.csv 文件中的结果:

如何使用 Python 抓取 Google 搜索结果

代码存储库可在 github 上获取

使用 apify 抓取 google 搜索结果

如果您正在从事需要数百万个数据点的大型项目,例如本文中有关 google 排名分析的项目 - 您可能需要一个现成的解决方案。

考虑使用 apify 团队开发的 google 搜索结果抓取器。

它提供了重要的功能,例如:

  • 代理支持
  • 大规模数据提取的可扩展性
  • 地理位置控制
  • 与 zapier、make、airbyte、langchain 等外部服务集成

您可以在 apify 博客中了解更多信息

你会刮什么?

在本博客中,我们逐步探索了如何创建收集排名数据的 google 搜索抓取工具。如何分析此数据集取决于您!

温馨提示,您可以在 github 上找到完整的项目代码。

我想 5 年后我需要写一篇关于“如何从 llm 的最佳搜索引擎中提取数据”的文章,但我怀疑 5 年后这篇文章仍然具有相关性。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
chrome什么意思
chrome什么意思

chrome是浏览器的意思,由Google开发的网络浏览器,它在2008年首次发布,并迅速成为全球最受欢迎的浏览器之一。本专题为大家提供chrome相关的文章、下载、课程内容,供大家免费下载体验。

1057

2023.08.11

chrome无法加载插件怎么办
chrome无法加载插件怎么办

chrome无法加载插件可以通过检查插件是否已正确安装、禁用和启用插件、清除插件缓存、更新浏览器和插件、检查网络连接和尝试在隐身模式下加载插件方法解决。更多关于chrome相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

838

2023.11.06

Python爬虫获取数据的方法
Python爬虫获取数据的方法

Python爬虫可以通过请求库发送HTTP请求、解析库解析HTML、正则表达式提取数据,或使用数据抓取框架来获取数据。更多关于Python爬虫相关知识。详情阅读本专题下面的文章。php中文网欢迎大家前来学习。

293

2023.11.13

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

530

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

576

2023.07.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

6207

2023.08.17

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

492

2023.09.01

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

CSS教程
CSS教程

共754课时 | 42.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号