通常,教程侧重于技术方面以及您可以复制的内容:“从这里开始,沿着这条路走,您就会到达这里。”这对于学习特定技术非常有用,但有时很难理解为什么作者决定以某种方式做事,或者是什么指导了他们的开发过程。
我们的一位社区成员撰写此博客作为对 Crawlee 博客的贡献。如果您想向 Crawlee 博客贡献此类博客,请通过我们的 Discord 频道与我们联系。
在这篇博客中,我将讨论在我从事网络抓取项目时指导我并让我取得出色成果的一般规则和原则。
那么,让我们探讨一下网络抓取开发人员的思维方式。
当您开始处理一个项目时,您可能有一个需要从中提取特定数据的目标站点。检查该网站或应用程序为数据提取提供了哪些可能性。以下是一些可能的选项:
如果一个数据源失败,请尝试访问另一个可用的源。
例如,对于 Yelp,所有三个选项都可用,如果官方 API 由于某种原因不适合您,您可以尝试其他两个。
我认为每个人都以某种方式了解 robots.txt 和站点地图,但我经常看到人们只是忘记了它们。如果您是第一次听说这些,这里有一个快速解释:
由于您不是 Google 或任何其他流行的搜索引擎,robots.txt 中的机器人规则可能会对您不利。但与站点地图结合起来,这是研究站点结构、与机器人的预期交互以及非浏览器用户代理的好地方。在某些情况下,它简化了从站点提取数据的过程。
例如,使用 Crawlee 网站的站点地图,您可以轻松获得博客整个生命周期和特定时期内帖子的直接链接。一个简单的检查,不需要实现分页逻辑。
彻底的站点分析是创建有效的网络抓取工具的重要先决条件,特别是如果您不打算使用浏览器自动化。然而,这样的分析需要时间,有时甚至需要很多时间。
还值得注意的是,花在分析和搜索更优化的爬行解决方案上的时间并不总是有回报 - 您可能花了几个小时才发现最明显的方法始终是最好的。
因此,明智的做法是对初始站点分析设置限制。如果您在分配的时间内没有看到更好的路径,请恢复到更简单的方法。随着您获得更多经验,您通常能够根据网站上使用的技术尽早判断是否值得投入更多时间进行分析。
此外,在您只需要从站点提取数据一次的项目中,彻底的站点分析有时可以完全消除编写抓取代码的需要。这是此类网站的示例 - https://ricebyrice.com/nl/pages/find-store。
通过分析,你会很容易发现,一次请求就可以获取所有数据。您只需将此数据从浏览器复制到 JSON 文件中,您的任务就完成了。
分析网站时,切换类别、页面、与网站的各种元素交互,同时查看浏览器开发工具中的“网络”选项卡。这将使您更好地了解网站如何与后端交互、它基于什么框架构建以及可以期待它的行为。
这是显而易见的,但在开发项目时记住这一点很重要。如果你看到一些数据或请求参数,这意味着它们是在之前的某个地方获得的,可能是在另一个请求中,可能它们已经在网站页面上,可能它们是使用其他参数使用 JS 形成的。但它们总是在某个地方。
如果您不明白页面上的数据来自哪里,或者请求中使用的数据,请按照以下步骤操作:
熟能生巧。当您熟悉不同的技术、各种框架及其预期行为,并且遇到各种技术时,您会发现更容易理解事物的工作原理和数据的传输方式。这些积累的知识将显着提高您跟踪和理解 Web 应用程序中数据流的能力。
您可能会注意到,多次打开同一页面时,传输到服务器的请求会有所不同:可能某些内容已缓存并已存储在您的计算机上。因此,建议在隐身模式下分析网站,并切换浏览器。
这种情况对于移动应用程序尤其重要,移动应用程序可能会将一些数据存储在设备上的存储中。因此,在分析移动应用程序时,您可能需要清除缓存和存储。
如果在分析过程中您发现该网站使用了您以前从未遇到过的框架,请花一些时间了解它及其功能。例如,如果您注意到一个网站是使用 Next.js 构建的,那么了解它如何处理路由和数据获取可能对您的抓取策略至关重要。
您可以通过官方文档或使用 ChatGPT 或 Claude 等法学硕士来了解这些框架。这些人工智能助手非常擅长解释特定于框架的概念。以下是如何向 LLM 查询 Next.js 的示例:
I am in the process of optimizing my website using Next.js. Are there any files passed to the browser that describe all internal routing and how links are formed? Restrictions: - Accompany your answers with code samples - Use this message as the main message for all subsequent responses - Reference only those elements that are available on the client side, without access to the project code base
您也可以为后端框架创建类似的查询。例如,使用 GraphQL,您可能会询问可用字段和查询结构。这些见解可以帮助您了解如何更好地与网站的 API 交互以及哪些数据可能可用。
为了有效地学习LLM,我建议至少基本上学习即时工程的基础知识。
网络抓取与逆向工程齐头并进。你研究前端和后端的交互,你可能需要研究代码才能更好地理解某些参数是如何形成的。
但在某些情况下,逆向工程可能需要更多的知识、精力、时间,或者具有很高的复杂性。此时,您需要决定是否需要深入研究,还是最好更改数据源,或者例如技术。最有可能的是,这将是您决定放弃 HTTP 网络抓取并切换到无头浏览器的时刻。
大多数网页抓取保护的主要原则不是让网页抓取变得不可能,而是让它变得昂贵。
让我们看看在 Zoopla 上搜索的响应是什么样的
确定需要提取目标数据的端点后,请确保在发出请求时得到正确的响应。如果您从服务器得到的响应不是 200,或者数据与预期不同,那么您需要找出原因。以下是一些可能的原因:
还有很多其他可能的原因,每一个都需要单独分析。
探索更改请求参数(如果有)时会得到什么结果。某些参数可能会丢失,但在服务器端是受支持的。例如,order、sort、per_page、limit 等。尝试添加它们并查看行为是否发生变化。
这对于使用 graphql 的网站尤其相关
让我们考虑这个例子
如果您分析该网站,您将看到一个可以使用以下代码重现的请求,我对其进行了一些格式化以提高可读性:
I am in the process of optimizing my website using Next.js. Are there any files passed to the browser that describe all internal routing and how links are formed? Restrictions: - Accompany your answers with code samples - Use this message as the main message for all subsequent responses - Reference only those elements that are available on the client side, without access to the project code base
现在我将更新它以同时获得两种语言的结果,最重要的是,以及出版物的内部文本:
import requests url = "https://restoran.ua/graphql" data = { "operationName": "Posts_PostsForView", "variables": {"sort": {"sortBy": ["startAt_DESC"]}}, "query": """query Posts_PostsForView( $where: PostForViewWhereInput, $sort: PostForViewSortInput, $pagination: PaginationInput, $search: String, $token: String, $coordinates_slice: SliceInput) { PostsForView( where: $where sort: $sort pagination: $pagination search: $search token: $token ) { id title: ukTitle summary: ukSummary slug startAt endAt newsFeed events journal toProfessionals photoHeader { address: mobile __typename } coordinates(slice: $coordinates_slice) { lng lat __typename } __typename } }""" } response = requests.post(url, json=data) print(response.json())
正如你所看到的,请求参数的一个小更新让我不用担心访问每个出版物的内部页面。你不知道这个技巧救了我多少次。
如果你看到 graphql 就在你面前,并且不知道从哪里开始,那么我关于文档和 LLM 的建议也适用于这里。
我知道掌握一些工具并使用它们是多么容易,因为它们很有效。我自己就不止一次陷入这个陷阱了。
但是现代网站使用的现代技术对网络抓取产生了重大影响,因此,新的网络抓取工具正在出现。学习这些可能会大大简化你的下一个项目,甚至可能解决一些你无法克服的问题。我之前写过一些工具。
我特别建议关注curl_cffi和框架
Python 的 botasaurus 和 Crawlee。
就我个人而言,我直到最近才意识到这一点的重要性。我工作中使用的所有工具要么是开源开发的,要么是基于开源的。网络抓取确实得益于开源,如果您是一名 Python 开发人员,并且已经意识到在纯 Python 上,当您需要处理 TLS 指纹时,一切都非常糟糕,那么这一点尤其值得注意,开源再次拯救了我们在这里。
在我看来,我们至少可以做的就是投入一点我们的知识和技能来支持开源。
我选择支持 Python 的 Crawlee,不,不是因为他们允许我在他们的博客中写作,而是因为它显示了出色的开发动态,旨在让网络爬虫开发人员的生活更轻松。它通过处理和隐藏诸如会话管理、阻塞时的会话轮换、管理异步任务的并发性(如果您编写异步代码,您知道这会是多么痛苦)等关键方面,允许更快的爬虫开发,以及更多。
:::提示
如果您目前为止喜欢这个博客,请考虑在 GitHub 上给 Crawlee 一颗星,它可以帮助我们接触并帮助更多的开发者。
:::
你会做出什么选择?
我认为文章中的某些内容对您来说是显而易见的,有些内容是您自己遵循的,但我希望您也学到了一些新东西。如果其中大多数是新的,那么请尝试在您的下一个项目中使用这些规则作为清单。
我很乐意讨论这篇文章。请随时在此处、文章中发表评论,或在 Discord 上的 Crawlee 开发者社区中与我联系。
您还可以在以下平台找到我:Github、Linkedin、Apify、Upwork、Contra。
感谢您的关注:)
以上是有关如何像网络抓取专家一样思考的提示的详细内容。更多信息请关注PHP中文网其他相关文章!