学习技术最好的方法是阅读源代码并动手写代码:阅读优秀成熟项目源代码和文档,跟随项目的示例程序和测试用例执行、修改、添加,最后尝试修改成熟项目的核心代码。
教材能够起到的作用非常有限,尤其不建议购买纸质教材,不建议看视频教程。
网络爬虫在各种语言中都有实现,譬如 Java, Kotlin, Javascript, Python, Go, C++ 等。随着网站变得越来越复杂,页面变动越来越频繁,越来越多的网站由 Vue,ReactJs 等技术动态生成,我们建议网络爬虫直接从浏览器自动化工具开始,譬如 Selenium,Playwright,Puppeteer,Crawlee,PulsarR 等。这些工具本身由某一种语言编写,但往往对使用者提供了多种语言绑定。
譬如,Selenium 由 Java 编写,但是提供了 Java, Python, C#, Ruby, JavaScript, Perl, PHP, R, Objective-C, Haskell 这些语言的编程接口;Playwright 由 Javascript 写成,但是提供了 JavaScript, Java, Python, C# 的编程接口。
选择什么语言开始你的爬虫之旅,需要综合考虑当前需求和职业规划。
如果只是临时性解决问题,那么 Crawlee/PulsarR 就是很好的选择,它们是开箱即用的,解决了阻挡在你和网页数据之间的绝大多数拦路虎。此时不建议选用 Selenium,Playwright,Puppeteer,如果使用它们,还有一大批技术问题需要解决。
如果希望从爬虫入手开始自己的职业生涯,那么 Java 语言就是很好的选择,因为工作机会多。
如果你要学习高级爬虫知识,譬如:
或者如果你是专业人士,需要解决最具挑战的网络数据采集问题,譬如:
那么,PulsarR 是你唯一的选择。
PulsarR(国内镜像)为解决网络数据管理、多源异构数据融合、数据采集等问题,开发了一系列基础设施和前沿技术。类似 Playwright 这样的浏览器驱动,在 PulsarR 中仅仅只是一个不大的子系统,可见单单 Playwright 能够解决的问题极其有限。为了性能、稳定性、容错性等考虑,我们也不会使用 Playwright 作为浏览器驱动,而是基于 CDP 从头开发。
目前大家常用的主流的数据采集软件,包括 selenium, playwright, puppeteer 等,不是为数据采集开发的,不适合数据采集;而大家熟知的 scrapy, requests 等,已经越来越不适应现代网页了。
即使解决完上述问题,也仅仅是入门而已。在稍稍正式一点的采集场景下,仍然面临诸多困难:
我们提供了大量顶级站点的采集示例,从入门到资深,包含各种采集模式,包括顶尖大站的全站采集代码、反爬天花板的站点的采集示例,你可以找一个代码示例改改就可以用于自己的项目:
我们的开源代码也包含 REST 服务、像数据库客户端一样的网页客户端等等,基于该网页客户端,你甚至可以稍稍完善一些用户体验就可以打造与最知名“采集器”相媲美的产品。
PulsarR 支持高质量的大规模数据采集和处理。PulsarR 开发了一系列基础设施和前沿技术,来保证即使是大规模数据采集场景,也能达到最高标准的性能、质量和总体拥有成本。
PulsarR 支持网络即数据库范式。PulsarR 像对待内部数据库一样对待外部网络,如果需要的数据不在本地存储中,或者现存版本不满足分析需要,则系统会从互联网上采集该数据的最新版本。我们也可以使用简单的 SQL 将 Web 直接转换为表格和图表,更进一步,我们可以使用 SQL 直接查询 Web。
PulsarR 支持浏览器渲染并将其作为数据采集的首要方法。将浏览器渲染作为数据采集的首要方法,我们在数据点规模、数据质量、人力成本和硬件成本之间实现了最佳平衡,并实现了最低的总体拥有成本。通过优化,如屏蔽不相关的资源文件,浏览器渲染的性能甚至可以与传统的单一资源采集方法相媲美。
PulsarR 支持 RPA 采集。PulsarR 包含一个 RPA 子系统,来实现网页交互:滚动、打字、屏幕捕获、鼠标拖放、点击等。该子系统和大家所熟知的 selenium, playwright, puppeteer 是类似的,但对所有行为进行了优化,譬如更真实的模拟操作,更好的执行性能,更好的并行性,更好的容错处理,等等。
PulsarR 支持退化的单一资源采集。PulsarR 的默认采集方式是通过浏览器渲染来采集完整的网页数据,如果您需要的数据可以通过单一接口获取,譬如可以通过某个 ajax 接口返回,也可以调用 PulsarR 的资源采集方法进行高速采集。
PulsarR 计划支持最前沿的信息提取技术。我们计划发布一个先进的人工智能,以显著的精度自动提取所有网页(譬如商品详情页)中的每一个字段,目前我们提供了一个预览版本,国内镜像。
大多数 抓取尝试 可以从几乎一行代码开始:
fun main() = PulsarContexts.createSession().scrapeOutPages( "https://www.amazon.com/", "-outLink a[href~=/dp/]", listOf("#title", "#acrCustomerReviewText"))
上面的代码从一组产品页面中抓取由 css 选择器 #title 和 #acrCustomerReviewText 指定的字段。 示例代码可以在这里找到:kotlin,java,国内镜像:kotlin,java。
大多数 生产环境 数据采集项目可以从以下代码片段开始:
fun main() {
val context = PulsarContexts.create()
val parseHandler = { _: WebPage, document: Document ->
// use the document
// ...
// and then extract further hyperlinks
context.submitAll(document.selectHyperlinks("a[href~=/dp/]"))
}
val urls = LinkExtractors.fromResource("seeds10.txt")
.map { ParsableHyperlink("$it -refresh", parseHandler) }
context.submitAll(urls).await()
}
示例代码可以在这里找到:kotlin,java,国内镜像:kotlin,java。
最复杂的数据采集项目可以使用 RPA 模式:
最复杂的数据采集项目往往需要和网页进行复杂交互,为此我们提供了简洁强大的 API。以下是一个典型的 RPA 代码片段,它是从顶级电子商务网站收集数据所必需的:
val options = session.options(args)
val event = options.event.browseEvent
event.onBrowserLaunched.addLast { page, driver ->
// warp up the browser to avoid being blocked by the website,
// or choose the global settings, such as your location.
warnUpBrowser(page, driver)
}
event.onWillFetch.addLast { page, driver ->
// have to visit a referrer page before we can visit the desired page
waitForReferrer(page, driver)
// websites may prevent us from opening too many pages at a time, so we should open links one by one.
waitForPreviousPage(page, driver)
}
event.onWillCheckDocumentState.addLast { page, driver ->
// wait for a special fields to appear on the page
driver.waitForSelector("body h1[itemprop=name]")
// close the mask layer, it might be promotions, ads, or something else.
driver.click(".mask-layer-close-button")
}
// visit the URL and trigger events
session.load(url, options)