想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。
6年前关闭。
Improve this question
我需要从网站中提取内容,但是该应用程序未提供任何应用程序编程接口(interface)或其他机制来以编程方式访问该数据。
我找到了一个有用的第三方工具Import.io,该工具提供了用于抓取网页和构建数据集的即点即用功能,唯一的是我想将数据保留在本地,并且我不想订阅任何订阅计划。
该公司使用哪种技术来抓取网页并构建其数据集?我发现一些网络抓取框架pjscrape和Scrapy可以提供这种功能吗
最佳答案
您肯定会想从一个好的Web抓取框架开始。稍后您可能会认为它们太过局限了,可以将自己的库放在一起,但是没有大量的抓图经验,那么您的设计就会比pjscrape或scrapy糟糕得多。
注意:我在这里使用的术语“抓取和抓取”基本上可以互换。这是我对您的Quora问题的回答的副本,非常长。
工具
根据您喜欢的浏览器,熟悉Firebug或Chrome开发者工具。当您浏览要从中提取数据的站点并确定包含所需数据的URL和构成响应的数据格式时,这是绝对必要的。
您将需要具备HTTP和HTML的良好工作知识,并且可能希望在中间代理软件中找到一位像样的人。您将需要能够检查HTTP请求和响应,并了解如何传递cookie和 session 信息以及查询参数。 Fiddler(http://www.telerik.com/fiddler)和Charles Proxy(http://www.charlesproxy.com/)是流行的工具。我经常使用mitmproxy(http://mitmproxy.org/),因为我更喜欢键盘而不是鼠标。
在某种控制台/ shell / REPL类型的环境中,您可以尝试各种具有即时反馈的代码,这将是非常宝贵的。像这样的逆向工程任务需要大量的反复试验,因此您需要一个工作流程来简化这一过程。
语言
PHP基本上已经淘汰了,它不太适合此任务,并且库/框架在该 Realm 的支持很差。 Python(Scrapy是一个很好的起点)和Clojure / Clojurescript(功能强大,高效但学习曲线很大)是解决此问题的出色语言。由于您宁愿不学习新语言并且已经知道Java语言,因此我绝对建议您坚持使用JS。我没有使用过pjscrape,但是从快速阅读他们的文档来看,它看起来相当不错。它非常适合并为我在下面描述的问题提供了出色的解决方案。
关于正则表达式的注释:
不要使用常规表达式来解析HTML。
许多初学者这样做是因为他们已经对正则表达式很熟悉。这是一个很大的错误,请使用xpath或CSS选择器浏览html,而仅使用正则表达式从html节点内的实际文本中提取数据。这对您可能已经很明显了,如果您尝试一下,它将很快变得很明显,但是很多人由于某种原因而浪费大量时间。不要害怕xpath或css选择器,它们比正则表达式更容易学习,并且它们旨在解决这个确切的问题。
Java重磅站点
在过去,您只需要发出http请求并解析HTML响应即可。现在,您几乎肯定会要处理由标准HTML HTTP请求/响应和目标网站的javascript部分进行的异步HTTP调用混合而成的网站。在这里,您的代理软件和firebug / devtools的网络选项卡非常方便。这些响应可能是html或json,在极少数情况下,它们将是xml或其他名称。
有两种方法可以解决此问题:
低级方法:
您可以弄清楚网站javascript调用的ajax网址是什么,这些响应是什么样的,您可以自己发出相同的请求。因此,您可能从http://example.com/foobar中提取html并提取一条数据,然后不得不从http://example.com/api/baz?foo=b中提取json响应...以获取另一条数据。您需要注意传递正确的cookie或 session 参数。这种情况很少见,但是偶尔会发生一些ajax调用所需的参数,这些参数是在网站的javascript中进行疯狂计算的结果,而进行反向工程可能会很烦人。
嵌入式浏览器方法:
为什么需要确定html中包含哪些数据以及ajax调用中包含的数据?管理所有的 session 和cookie数据?当您浏览网站时,您不必这样做,浏览器和网站javascript都可以做到这一点。这就是重点。
如果您只是将页面加载到像phantomjs这样的无头浏览器引擎中,它将加载页面,运行javascript并告诉您所有ajax调用何时完成。您可以根据需要注入(inject)自己的javascript,以触发相应的点击,或触发站点javascript加载适当的数据所需的任何触发。
现在,您有两个选择,可以通过它吐出完成的html并进行解析,也可以将一些javascript注入(inject)执行解析和数据格式化并吐出数据的页面(可能为json格式)。您也可以随意混合使用这两个选项。
哪种方法最好?
这取决于您,您肯定需要熟悉并熟悉低级方法。嵌入式浏览器方法适用于任何事物,将更易于实现,并使某些最棘手的抓取问题消失。这也是您需要了解的非常复杂的机器。它不仅是HTTP请求和响应,还包括请求,嵌入式浏览器呈现,站点javascript,注入(inject)的javascript,您自己的代码以及与嵌入式浏览器进程的2向交互。
由于渲染开销,嵌入式浏览器在规模上也要慢得多,但是除非您要抓取许多不同的域,否则几乎可以肯定这无关紧要。如果需要限制请求的速率,则在单个域的情况下,渲染时间可以完全忽略。
速率限制/启动行为
您需要非常注意这一点。您需要以合理的速率向目标域提出请求。在抓取网站时,您需要编写行为良好的bot,这意味着要尊重robots.txt,而不要对服务器提出要求。错误或疏忽在这里是非常不道德的,因为这可以被视为拒绝服务攻击。可接受的速率取决于您询问的人,1req / s是Google搜寻器运行的最高速度,但您不是Google,并且您可能不如Google受欢迎。使其保持尽可能慢的速度。我建议每个页面请求之间2-5秒。
使用用户代理字符串标识您的请求,该字符串标识您的机器人并为您的机器人提供一个网页,以说明其用途。该网址在代理字符串中。
如果该网站想阻止您,您将很容易被阻止。末端的智能工程师可以轻松地识别机器人,而末端的几分钟工作可能会导致数周的工作最终更改您的抓取代码,或者只是使其变为不可能。如果这种关系是对立的,那么目标站点的聪明工程师可以完全阻止编写爬虫的天才工程师。爬网代码本质上是脆弱的,很容易被利用。无论如何,几乎可以肯定会引起这种反应的事情是不道德的,因此编写行为良好的bot不必担心。
测试
不是单元/集成测试人员?太糟糕了。您现在必须成为一个。网站经常更改,您将经常更改代码。这是挑战的很大一部分。
抓取现代网站涉及很多 Activity 部件,良好的测试习惯将有很大帮助。在编写这种类型的代码时,您将遇到的许多错误将只是以静默方式返回损坏的数据。没有良好的测试来检查回归,您会发现一段时间以来一直在将无用的损坏数据保存到数据库中而没有注意到。该项目将使您非常熟悉数据验证(找到一些不错的库以供使用)和测试。没有其他许多问题需要综合测试并且很难测试。
测试的第二部分涉及缓存和更改检测。在编写代码时,您不会无缘无故地反复为同一页面锤击服务器。在运行单元测试时,您想知道测试是否由于代码中断或网站经过重新设计而失败。针对所涉及的URL的缓存副本运行单元测试。缓存代理在这里非常有用,但是要正确配置和使用它很棘手。
您还想知道站点是否已更改。如果他们重新设计了站点,并且您的搜寻器损坏了,则由于它们针对缓存副本运行,因此单元测试仍将通过!您将需要另一套较小的,不经常在实时站点上运行的集成测试,或者需要在爬网代码中进行良好的日志记录和错误检测,以准确记录问题,向您发出警报并停止爬网。现在,您可以更新缓存,运行单元测试并查看需要更改的内容。
法律问题
如果您做愚蠢的事情,这里的法律可能会有些危险。如果法律介入,您将与经常将wget和curl称为“黑客工具”的人打交道。你不要这个
这种情况的道德现实是,使用浏览器软件请求url和查看某些数据与使用您自己的软件请求url和查看某些数据之间没有区别。 Google是世界上最大的刮板公司,因此受到了喜爱。在法律上了解Google是什么之后,在用户代理中标识您的漫游器名称并公开网络爬虫的目标和意图将对您有所帮助。如果您在做任何不受欢迎的事情,例如创建虚假的用户帐户或访问不应访问的网站区域(被robots.txt“阻止”或由于某种授权利用而被阻止),那么请注意您所做的事情是不道德的法律对技术的无知在这里将是极其危险的。这是一个荒谬的情况,但这是真实的情况。
从字面上看,有可能尝试以一个正直的公民不断建立一个新的搜索引擎,犯错或在软件中出现错误,并被视为黑客。您不必考虑当前的政治现实。
我到底是谁来写这段巨大的文字墙?
我一生中编写了许多与Web爬网相关的代码。作为顾问,员工和创业者,我从事与网络相关的软件开发已有十多年了。早期写Perl爬虫/爬虫和php网站。当我们嵌入隐藏的iframe并将csv数据加载到网页中进行ajax之前,Jesse James Garrett将其命名为ajax,而XMLHTTPRequest是一个想法。在jQuery之前,在json之前。我正处于30多岁的年龄,这显然被认为是一项古老的业务。
我已经编写了两次大型爬网/爬网系统,一次是为一家媒体公司的大型团队(在Perl中)编写的,最近一次是为一个小团队作为搜索引擎初创公司的CTO(在Python / Javascript中)编写的。我目前是一名顾问,主要使用Clojure / Clojurescript(一般来说是一种出色的专家语言,并且具有使爬虫/爬虫问题变得令人愉悦的库)进行编码。
我也写了成功的防爬网软件系统。如果您愿意或者很难识别和破坏机器人,那么编写几乎无法捕获的站点非常容易。
我比其他任何类型的软件都更喜欢编写搜寻器,搜寻器和解析器。它具有挑战性,趣味性,可用于创造惊人的事物。
关于api - 从网站抓取数据的最佳方法是什么? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22168883/