php 正则 抓取网页(Python(Scrapy)是解决这个问题的好语言(图))
优采云 发布时间: 2022-01-24 17:10php 正则 抓取网页(Python(Scrapy)是解决这个问题的好语言(图))
你肯定想从一个好的网络抓取框架开始。后来你可能会认为它们太有限了,你可以把自己的库放在一起,但是如果没有大量的爬取经验,你的设计会比 pjscrape 或 scrapy 差很多。
注意:我在这里使用的术语“爬行”和“爬行”基本上可以互换使用。这是我对你的 Quora 问题的回答的副本,它很长。
工具
熟悉 Firebug 或 Chrome 开发工具,具体取决于您喜欢的浏览器。当您浏览要从中提取数据的站点并确定哪些 url 收录您要查找的数据以及构成响应的数据格式时,这将是绝对必要的。
您需要具备良好的 HTTP 和 HTML 工作知识,并且可能希望在中间代理软件中找到一个不错的。您需要能够检查 HTTP 请求和响应,并了解 cookie 和会话信息以及查询参数是如何传递的。Fiddler() 和 Charles Proxy() 是流行的工具。我经常使用 mitmproxy() 因为我更喜欢键盘侠而不是鼠标手。
某种控制台/shell/REPL 类型的环境,您可以在其中尝试各种具有即时反馈的代码片段,这将是非常宝贵的。像这样的逆向工程任务需要大量的反复试验,因此您需要一个可以简化流程的工作流程。
语
PHP 基本上已经过时了,它不太适合这项任务,并且对此的库/框架支持很差。Python(Scrapy 是一个很好的起点)和 Clojure/Clojurescript(非常强大和高效,但学习曲线很大)是解决这个问题的好语言。由于您不想学习一门新语言并且您已经了解 Javascript,因此我绝对建议您坚持使用 JS。我没有使用过 pjscrape,但是从他们的文档快速阅读来看,它看起来相当不错。它非常适合并为我在下面描述的问题实现了出色的解决方案。
正则表达式注意事项:不要使用正则表达式解析 HTML。许多初学者这样做是因为他们已经熟悉正则表达式。使用 xpath 或 css 选择器来导航 html 并仅使用正则表达式从 html 节点内的实际文本中提取数据是一个巨大的错误。这对你来说可能已经很明显了,如果你尝试一下,它很快就会变得明显,但是很多人出于某种原因在路上浪费了很多时间。不要害怕 xpath 或 css 选择器,它们比正则表达式更容易学习,它们旨在解决这个确切的问题。
Javascript 密集型网站
过去,您只需要发出一个 http 请求并解析 HTML 响应。现在,您几乎可以肯定必须处理由目标站点的 javascript 部分发出的标准 HTML HTTP 请求/响应和异步 HTTP 调用的混合。这是您的代理软件和 firebug/devtools 的网络选项卡派上用场的地方。对这些的响应可能是 html 或 json,在极少数情况下它们会是 xml 或其他东西。
有两种方法可以解决这个问题:
低级方法:
您可以找出 ajax urls 网站 javascript 正在调用什么以及这些响应是什么样的,并自己提出相同的请求。因此,您可能会从中提取 html 并提取一条数据,然后必须从中提取 json 响应以获取另一条数据。您需要注意传递正确的 cookie 或会话参数。这种情况非常少见,但有时 ajax 调用所需的一些参数是 网站 的 javascript 中一些疯狂计算的结果,这对逆向工程师来说可能很烦人。
嵌入式浏览器方法:
为什么需要弄清楚 html 中有哪些数据以及来自 ajax 调用的数据是什么?管理所有会话和 cookie 数据?浏览 网站 时不必这样做,浏览器和 网站 javascript 会这样做。这才是重点。
如果您只是将页面加载到像 phantomjs 这样的无头浏览器引擎中,它将加载页面、运行 javascript 并告诉您所有 ajax 调用何时完成。如有必要,您可以注入自己的 javascript 以触发适当的点击或触发 网站 javascript 以加载适当的数据所需的任何内容。
您现在有两个选择,让它吐出完成的 html 并解析它,或者将一些 javascript 注入页面以进行解析和数据格式化并吐出数据(可能是 json)。您也可以自由混合这两个选项。
哪种方法最好?
这取决于,您肯定需要熟悉并习惯低级方法。嵌入式浏览器方法适用于任何事情,更容易实现,并且可以解决抓取中一些最棘手的问题。它也是一个相当复杂的机器,你需要了解它。它不仅仅是 HTTP 请求和响应,还包括请求、嵌入式浏览器渲染、站点 javascript、注入的 javascript、您自己的代码以及与嵌入式浏览器进程的双向交互。
由于渲染开销,嵌入式浏览器在规模上也慢得多,但这几乎可以肯定是无关紧要的,除非你正在抓取许多不同的域。在单个域的情况下,您需要对请求进行速率限制以使渲染时间完全可以忽略不计。
速率限制/机器人行为
你需要非常清楚这一点。您需要以合理的速率向目标域发出请求。在抓取 网站 时,您需要编写一个行为良好的机器人,这意味着尊重 robots.txt,而不是向服务器发送请求。这里的错误或遗漏是非常*敏*感*词*的,因为这可以被视为拒绝服务攻击。可接受的速率取决于您询问的对象,1req/s 是 Google 爬虫将运行的最大速度,但您不是 Google,您可能不如 Google 受欢迎。保持合理的速度。我建议在每个页面请求之间间隔 2-5 秒。
使用用户代理字符串识别您的请求,该字符串可识别您的机器人并为您的机器人提供解释其用途的网页。此 URL 在代理字符串中。
如果一个网站想屏蔽你,你很容易被屏蔽。聪明的工程师可以轻松识别机器人,几分钟的工作可能会导致您花费数周的时间来更改抓取代码,或者只是让它变得不可能。如果关系是对立的,那么目标站点的智能工程师可以完全阻止编写爬虫的天才工程师。抓取代码本质上是脆弱的,很容易被利用。无论如何,几乎可以肯定会引起这种反应的事情是*敏*感*词*的,所以编写一个表现良好的机器人,不要担心。
测试
不是单元/集成测试人员?太坏了。你现在一定是他们中的一员。站点经常更改,您将经常更改代码。这是挑战的很大一部分。
Scraping Modern网站 涉及许多活动部件,良好的测试实践有很长的路要走。在编写这样的代码时会遇到的许多错误都是默默返回损坏数据的类型。如果没有良好的测试来检查回归,您会发现您已经将无用的损坏数据保存到数据库中一段时间而没有注意到。这个项目会让你非常熟悉数据验证(找到一些好的库来使用)和测试。其他需要综合测试且难于测试的问题并不多。
测试的第二部分涉及缓存和更改检测。编写代码时,您不想无缘无故地为同一个页面一遍又一遍地敲击服务器。运行单元测试时,您想知道测试失败是因为您破坏了代码还是因为重新设计了 网站。针对所涉及的 url 的缓存副本运行单元测试。缓存代理在这里非常有用,但很难正确配置和使用。
您还真的想知道该站点是否已更改。如果他们重新设计了站点并且您的爬虫损坏了,您的单元测试仍然会通过,因为它们是针对缓存的副本运行的!您将需要另一组很少在实时站点上运行的较小的集成测试,或者在爬网代码中进行良好的日志记录和错误检测,以记录确切的问题,提醒您问题并停止爬网。现在您可以更新缓存、运行单元测试并查看需要更改的内容。
法律问题
如果您做一些傻瓜式事情,这里的法律可能会有点危险。谈到法律,您所面对的人经常将 wget 和 curl 称为“黑客工具”。你不想要这个。
这种情况的道德现实是,使用浏览器软件请求 URL 并查看一些数据与使用您自己的软件请求 URL 并查看一些数据之间没有区别。谷歌是世界上最大的爬虫公司,他们深受喜爱。在用户代理中识别您的机器人名称并披露您的网络爬虫的目标和意图将在这里有所帮助,因为法律知道 Google 是什么。如果您正在做任何可疑的事情,例如创建虚假用户帐户或访问您不应该访问的网站区域(被 robots.txt “阻止”或由于某种授权漏洞),那么请注意您在做一些*敏*感*词*的事情并且在这里,对技术的法律无知将是极其危险的。这是一个荒谬的情况,但它是真实的。
作为一个诚实的公民,尝试构建一个新的搜索引擎是完全可能的,但有可能在你的软件中犯错误或存在错误,并被视为黑客。鉴于当前的政治现实,这不是你想要的。
我是谁来写这堵巨大的文字墙?
在我的生活中,我写了很多与网络爬虫相关的代码。作为一名顾问、员工和初创公司创始人,我开发网络相关软件已有十多年了。早期是写 perl crawlers/crawlers 和 php 网站。在 XMLHTTPRequest 成为一个想法之前,我们将其命名为 Jesse James Garrett 的 ajax,嵌入一个隐藏的 iframe 以将 csv 数据加载到网页中以执行 ajax。在 jQuery 之前,在 json 之前。我已经 30 多岁了,对于这个行业来说,这显然被认为是老了。
我编写了两个大型爬取/爬取系统,一次是为一家媒体公司的大型团队(使用 Perl)编写的,最近一次是为一个小型团队(使用 Python)作为搜索引擎初创公司 /Javascript 的 CTO)编写的。我目前是一名顾问编码,主要使用 Clojure/Clojurescript(一种很棒的专家语言,并且拥有使抓取/抓取问题成为一种乐趣的库)。
我还编写了成功的反爬虫软件系统。如果您想要或识别并破解您不喜欢的机器人,编写 网站nearly unbreakable 非常容易。
与任何其他类型的软件相比,我更喜欢编写爬虫、爬虫和解析器。它具有挑战性、趣味性,可以用来创造令人惊奇的事物。