从网站上获取数据的最好方法是什么?

我需要从一个网站提取内容,但应用程序没有提供任何应用程序编程接口或其他机制来访问该数据编程。

我发现了一个有用的第三方工具,名为 很重要,它提供了点击和访问功能,可以清理网页和建立数据集,唯一的问题是我想在本地保存我的数据,而且我不想订阅任何订阅计划。

这家公司使用什么样的技术来刮网页和建立他们的数据集?我发现一些网页抓取框架 pjscrapeScrapy可以提供这样的功能

166924 次浏览

是的,你可以自己做。这只是一个抓取页面源代码并按照您希望的方式解析它们的问题。

有各种各样的可能性。一个好的组合是使用 巨蟒请求(构建在 urllib2之上,在 Python 3中是 urllib.request)和 美味汤4,它有自己的方法来选择元素,并且允许 CSS 选择器:

import requests
from BeautifulSoup4 import BeautifulSoup as bs
request = requests.get("http://foo.bar")
soup = bs(request.text)
some_elements = soup.find_all("div", class_="myCssClass")

有些人更喜欢 xpath 解析或类似于 jquery 的 pyquery,Lxml 或者其他什么东西

当你想要的数据是由某些 JavaScript产生的时候,上面的方法就不起作用了。你要么需要蟒鬼,要么需要硒。我更喜欢后者的 结合了 PhantomJS,更轻,更简单的安装,易于使用:

from selenium import webdriver
client = webdriver.PhantomJS()
client.get("http://foo")
soup = bs(client.page_source)

我建议你开始自己的解决方案。你会明白这样做 Scrapy 的好处。

注意: 看一下大致情况: https://github.com/scrapy/scrapely

Pps: 看看 Portia,在没有编程知识的情况下,开始可视化地提取信息

You will definitely want to start with a good web scraping framework. Later on you may decide that they are too limiting and you can put together your own stack of libraries but without a lot of scraping experience your design will be much worse than pjscrape or scrapy.

注意: 我在这里使用的术语抓取和刮取基本上是可以互换的。这是我对你 Quora 问题的回答,很长。

工具

根据你的首选浏览器,熟悉 Firebug 或 Chrome 开发工具。当您浏览从中提取数据的站点时,这将是绝对必要的,并且可以绘制出包含您要查找的数据的 URL 以及构成响应的数据格式。

您将需要对 HTTP 和 HTML 有很好的工作知识,并且可能希望在中间代理软件中找到一个像样的人。您将需要能够检查 HTTP 请求和响应,并理解 cookie 和会话信息以及查询参数是如何传递的。Fiddler (http://www.telerik.com/fiddler)和 Charles Proxy (http://www.charlesproxy.com/)是流行的工具。我经常使用 mitmxy (http://mitmproxy.org/) ,因为我更喜欢用键盘而不是鼠标。

某种类型的控制台/shell/REPL 类型的环境,在这种环境中,您可以使用即时反馈尝试各种代码片段,这将是非常宝贵的。像这样的逆向工程任务需要反复试验,所以你需要一个简单的工作流程。

Language

PHP 基本上已经过时了,它不太适合这个任务,而且库/框架在这方面的支持也很差。Python (Scrapy 是一个很好的起点)和 Clojure/Clojurescript (非常强大和高效,但是需要很长的学习曲线)是解决这个问题的很好的语言。既然你不愿意学习一门新的语言,而且你已经知道 Javascript 了,我肯定会建议你坚持使用 JS。我没有使用 pjscrape,但它看起来相当不错,从快速阅读他们的文件。它非常适合并实现了我下面描述的问题的一个极好的解决方案。

A note on Regular expressions: 不要使用正则表达式解析 HTML。 很多初学者这样做是因为他们已经熟悉正则表达式。这是一个巨大的错误,使用 xpath 或 css 选择器来导航 html,并且只使用正则表达式来从 html 节点中的实际文本提取数据。这对你来说可能已经很明显了,如果你尝试一下,它会很快变得明显,但是很多人由于某些原因浪费了很多时间在这条路上。不要害怕 xpath 或 css 选择器,它们比正则表达式更容易学习,而且它们的设计就是为了解决这个问题。

Javascript-heavy sites

在过去,您只需要发出 http 请求并解析 HTML 响应。现在,几乎可以肯定,您必须处理由标准 HTML HTTP 请求/响应和目标站点的 javascript 部分发出的异步 HTTP 调用组成的站点。这就是代理软件和 firebug/devtools 的网络选项卡非常方便的地方。对这些的响应可能是 html,也可能是 json,在极少数情况下,它们将是 xml 或其他东西。

解决这个问题有两种方法:

低层次方法:

您可以弄清楚 javascript 调用的 Ajax URL 是什么,以及这些响应是什么样子,然后自己发出相同的请求。因此,您可以从 http://example.com/foobar中提取 html 并提取一段数据,然后必须从 http://example.com/api/baz?foo=b中提取 json 响应... 以获取另一段数据。您需要注意传递正确的 cookie 或会话参数。虽然这种情况很少见,但是有时候一个 ajax 调用所需的一些参数会是在 javascript 中进行疯狂计算的结果,这种逆向工程可能会很烦人。

嵌入式浏览器方法:

Why do you need to work out what data is in html and what data comes in from an ajax call? Managing all that session and cookie data? You don't have to when you browse a site, the browser and the site javascript do that. That's the whole point.

如果你只是把页面加载到一个像 phantomjs 这样的无头浏览器引擎中,它就会加载页面,运行 javascript 并告诉你所有的 ajax 调用什么时候完成。如果需要触发适当的单击或者触发站点 javascript 以加载适当的数据,您可以注入自己的 javascript。

现在有两个选项,让它输出完成的 html 并解析它,或者在页面中注入一些 javascript,这些 javascript 执行解析和数据格式化并输出数据(可能是 json 格式)。您也可以自由地混合这两个选项。

哪种方法最好?

That depends, you will need to be familiar and comfortable with the low level approach for sure. The embedded browser approach works for anything, it will be much easier to implement and will make some of the trickiest problems in scraping disappear. It's also quite a complex piece of machinery that you will need to understand. It's not just HTTP requests and responses, it's requests, embedded browser rendering, site javascript, injected javascript, your own code and 2-way interaction with the embedded browser process.

The embedded browser is also much slower at scale because of the rendering overhead but that will almost certainly not matter unless you are scraping a lot of different domains. Your need to rate limit your requests will make the rendering time completely negligible in the case of a single domain.

Rate Limiting/Bot behaviour

你要非常清楚这一点。您需要以合理的速度向您的目标域发出请求。在爬行网站时,需要编写一个行为良好的 bot,这意味着要尊重 robots.txt,而不是用请求敲击服务器。错误或疏忽在这里是非常不道德的,因为这可以被认为是一种分布式拒绝服务攻击攻击。可接受的速率取决于你询问的人,1req/s 是谷歌爬虫运行的最大速度,但你不是谷歌,你可能不像谷歌那样受欢迎。尽量慢一点。我建议每个页面请求间隔2-5秒。

Identify your requests with a user agent string that identifies your bot and have a webpage for your bot explaining it's purpose. This url goes in the agent string.

如果网站想要屏蔽你,你将很容易被屏蔽。一个聪明的工程师可以很容易地识别机器人和他们的一端几分钟的工作可以导致几个星期的工作改变你的刮代码在你的一端或只是使它不可能。如果这种关系是对立的,那么目标站点上的一个聪明的工程师可以完全阻碍一个天才工程师编写爬虫程序。刮取代码本质上是脆弱的,这很容易被利用。无论如何,会引起这种反应的东西几乎肯定是不道德的,所以写一个表现良好的 bot,不要担心这个。

测试

不是单元/集成测试人员?真可惜。你现在必须成为其中一员。网站经常更改,您将经常更改代码。这是挑战的一大部分。

一个现代网站有很多活动的部分,良好的测试实践会有很大的帮助。在编写此类代码时遇到的许多 bug 都只是默默地返回损坏的数据。如果没有好的测试来检查回归,您会发现,您已经将无用的损坏数据保存到数据库中有一段时间了,而没有注意到这一点。这个项目将使您非常熟悉数据验证(找到一些好的库来使用)和测试。没有许多其他问题需要综合测试和非常难以测试相结合。

The second part of your tests involve caching and change detection. While writing your code you don't want to be hammering the server for the same page over and over again for no reason. While running your unit tests you want to know if your tests are failing because you broke your code or because the website has been redesigned. Run your unit tests against a cached copy of the urls involved. A caching proxy is very useful here but tricky to configure and use properly.

您还想知道站点是否已经更改。如果他们重新设计了站点,而你的爬虫程序被破坏了,你的单元测试仍然会通过,因为它们是在缓存的拷贝上运行的!您将需要另一组较小的集成测试,这些测试很少在活动站点上运行,或者在您的爬行代码中进行良好的日志记录和错误检测,以记录确切的问题,提醒您问题并停止爬行。现在,您可以更新缓存、运行单元测试并查看需要更改的内容。

法律问题

如果你做了蠢事,这里的法律会有点危险。如果法律介入,你就是在和那些经常把 wget 和 curl 称为“黑客工具”的人打交道。你不会想这样的。

这种情况的道德现实是,使用浏览器软件请求 URL 并查看某些数据与使用自己的软件请求 URL 并查看某些数据没有区别。谷歌是世界上最大的刮纸公司,他们因此而受到人们的喜爱。在用户代理中识别你的机器人名称,并公开你的网络爬虫的目标和意图,这将有助于法律理解谷歌是什么。如果你正在做一些见不得人的事情,比如创建虚假的用户账户或者访问一些你不应该访问的网站区域(或者被 robots.txt“屏蔽”,或者因为某种授权漏洞) ,那么你应该意识到你正在做一些不道德的事情,而法律对技术的无知在这里将是非常危险的。这是一个可笑的情况,但它是一个真实的。

作为一个正直的公民,你完全有可能尝试建立一个新的搜索引擎,犯一个错误,或者在你的软件中有一个漏洞,然后被视为一个黑客。考虑到当前的政治现实,这可不是你想要的。

我有什么资格写这么一大堆文字?

在我的生活中,我写了很多与网络爬行相关的代码。作为一名顾问、员工和创业者,我从事网络相关软件开发已经超过十年了。早期的工作是编写 perl 爬虫/scraper 和 php 网站。当我们嵌入隐藏的 iframes 将 csv 数据加载到网页中来做 ajax 的时候,杰西·詹姆士·贾瑞特还没有把它命名为 ajax,在 XMLHTTPRequest 出现之前。在 jQuery 之前,在 json 之前。我现在35岁左右,在这个行业里,这显然被认为是老古董了。

我编写过两次大规模的爬行/抓取系统,一次是为一家媒体公司的大型团队(用 Perl 语言) ,最近是为一个小型团队(用 Python/Javascript 语言) ,作为搜索引擎初创公司的首席技术官。我目前是一名咨询师,大部分时间用的是 Clojure/Clojurescript (一种非常棒的专业语言,有一些库可以让爬虫/scraper 问题变得非常有趣)

我也写过成功的反爬行软件系统。如果你想的话,编写几乎不可破坏的网站或者识别和破坏你不喜欢的机器人是非常容易的。

与其他类型的软件相比,我更喜欢编写爬虫、抓取器和解析器。它具有挑战性,有趣,可以用来创造惊人的东西。