duzun / hquery
一款极快的网页爬虫,能在瞬间解析数兆字节HTML。无依赖。PHP5+
Requires
- php: >=5.3
Requires (Dev)
Suggests
- php-http/discovery: Might be required by hQuery::sendRequest()
- php-http/message: Might be required by hQuery::fromHTML($message) or hQuery::fromURL()
- php-http/socket-client: Could be used to make HTTP requests before calling hQuery::fromHTML($message)
- dev-master
- 3.2.0
- 3.1.1
- 3.1.0
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.0
- 2.0.3
- 2.0.2
- 2.0.1
- 1.7.4
- 1.7.3
- 1.7.2
- 1.7.1
- 1.7.0
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.3
- 1.5.2
- 1.5.1
- 1.5.0
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.0
- 1.2.5
- 1.2.4
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- dev-dependabot/npm_and_yarn/multi-a9f852c250
- dev-10x
This package is auto-updated.
Last update: 2024-09-17 20:43:09 UTC
README
一款极快且高效的网页爬虫,能在瞬间解析数兆字节无效HTML。
您可以使用熟悉的jQuery/CSS选择器语法轻松找到所需的数据。
在我的单元测试中,我要求它在3MB HTML文档上至少比Symfony的DOMCrawler快10倍。根据我谦逊的测试,在某些情况下,它比DOMCrawler快两个到三个数量级,平均使用内存减少x2。
请参阅。
💡功能
- 非常快的解析和查找
- 解析破碎的HTML
- 类似jQuery的DOM遍历风格
- 内存使用低
- 可以处理大型HTML文档(我已经测试到20MB,但限制是您拥有的RAM量)
- 不需要安装cURL,并自动处理重定向(请参阅hQuery::fromUrl())
- 为多个处理任务缓存响应
- PSR-7友好(请参阅hQuery::fromHTML($message))
- PHP 5.3+
- 无依赖
🛠安装
只需将此文件夹添加到您的项目中,然后include_once 'hquery.php';
,您就可以开始使用hQuery
了。
或者使用composer require duzun/hquery
或者使用npm install hquery.php
,require_once 'node_modules/hquery.php/hquery.php';
。
⚙使用方法
基本设置
// Optionally use namespaces use duzun\hQuery; // Either use composer, or include this file: include_once '/path/to/libs/hquery.php'; // Set the cache path - must be a writable folder // If not set, hQuery::fromURL() would make a new request on each call hQuery::$cache_path = "/path/to/cache"; // Time to keep request data in cache, seconds // A value of 0 disables cache hQuery::$cache_expires = 3600; // default one hour
我建议使用php-http/cache-plugin与一个PSR-7客户端以获得更好的灵活性。
从文件加载HTML
hQuery::fromFile( string $filename
, boolean $use_include_path
= false, resource $context
= NULL )
// Local $doc = hQuery::fromFile('/path/to/filesystem/doc.html'); // Remote $doc = hQuery::fromFile('https://example.com/', false, $context);
其中$context
是通过stream_context_create()创建的。
请参阅#26了解如何使用$context
通过代理进行HTTP请求的示例。
从字符串加载HTML
hQuery::fromHTML( string $html
, string $url
= NULL )
$doc = hQuery::fromHTML('<html><head><title>Sample HTML Doc</title><body>Contents...</body></html>'); // Set base_url, in case the document is loaded from local source. // Note: The base_url property is used to retrieve absolute URLs from relative ones. $doc->base_url = 'http://desired-host.net/path';
加载远程HTML文档
hQuery::fromUrl( string $url
, array $headers
= NULL, array|string $body
= NULL, array $options
= NULL )
use duzun\hQuery; // GET the document $doc = hQuery::fromUrl('http://example.com/someDoc.html', ['Accept' => 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8']); var_dump($doc->headers); // See response headers var_dump(hQuery::$last_http_result); // See response details of last request // with POST $doc = hQuery::fromUrl( 'http://example.com/someDoc.html', // url ['Accept' => 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8'], // headers ['username' => 'Me', 'fullname' => 'Just Me'], // request body - could be a string as well ['method' => 'POST', 'timeout' => 7, 'redirect' => 7, 'decode' => 'gzip'] // options );
有关构建高级请求(POST、参数等),请参阅hQuery::http_wr(),尽管我建议使用专门的(PSR-7)库来发送请求,并使用hQuery::fromHTML($html, $url=NULL)
来处理结果。例如,请参阅Guzzle。
PSR-7示例
composer require php-http/message php-http/discovery php-http/curl-client
如果您没有cURL PHP 扩展,只需在上面的命令中将 php-http/curl-client
替换为 php-http/socket-client
。
use duzun\hQuery; use Http\Discovery\HttpClientDiscovery; use Http\Discovery\MessageFactoryDiscovery; $client = HttpClientDiscovery::find(); $messageFactory = MessageFactoryDiscovery::find(); $request = $messageFactory->createRequest( 'GET', 'http://example.com/someDoc.html', ['Accept' => 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8'] ); $response = $client->sendRequest($request); $doc = hQuery::fromHTML($response, $request->getUri());
另一种选择是使用 stream_context_create() 来创建一个 $context
,然后调用 hQuery::fromFile($url, false, $context)
。
处理结果
hQuery::find( string $sel
, array|string $attr
= NULL, hQuery\Node $ctx
= NULL )
// Find all banners (images inside anchors) $banners = $doc->find('a[href] > img[src]:parent'); // Extract links and images $links = array(); $images = array(); $titles = array(); // If the result of find() is not empty // $banners is a collection of elements (hQuery\Element) if ( $banners ) { // Iterate over the result foreach($banners as $pos => $a) { $links[$pos] = $a->attr('href'); // get absolute URL from href property $titles[$pos] = trim($a->text()); // strip all HTML tags and leave just text // Filter the result if ( !$a->hasClass('logo') ) { // $a->style property is the parsed $a->attr('style') if ( strtolower($a->style['position']) == 'fixed' ) continue; $img = $a->find('img')[0]; // ArrayAccess if ( $img ) $images[$pos] = $img->src; // short for $img->attr('src') } } // If at least one element has the class .home if ( $banners->hasClass('home') ) { echo 'There is .home button!', PHP_EOL; // ArrayAccess for elements and properties. if ( $banners[0]['href'] == '/' ) { echo 'And it is the first one!'; } } } // Read charset of the original document (internally it is converted to UTF-8) $charset = $doc->charset; // Get the size of the document ( strlen($html) ) $size = $doc->size;
注意:如果字符集元属性有错误值或由于其他任何原因内部转换失败,hQuery
将忽略错误并继续使用原始 HTML 进行处理,但会在 $doc->html_errors['convert_encoding']
上注册一个错误信息。
🖧 在线演示
在 DUzun.Me
很多人询问我的 在线演示 页面的来源。这里就是
view-source:https://duzun.me/playground/hquery
🏃 运行游乐场
您可以在本地机器上轻松运行 examples/
中的任何示例。您只需要在系统中安装 PHP。在用 git clone https://github.com/duzun/hQuery.php.git
克隆仓库后,您有几个选项来启动一个 web 服务器。
选项 1
cd hQuery.php/examples php -S localhost:8000 # open browser https://:8000/
选项 2 (browser-sync)
此选项启动一个实时重新加载服务器,适用于与代码交互。
npm install
gulp
# open browser https://:8080/
选项 3 (VSCode)
如果您正在使用 VSCode,只需打开项目并运行调试器(F5
)。
🔧 TODO
- 对一切进行单元测试
- 记录一切
Cookie 支持(在 mem 中实现以处理重定向)改进选择器,以便可以通过属性进行选择- 添加更多选择器
- 在内部使用 HTTPlug
💖 支持我的项目
我喜欢开源。只要可能,我都会与世界分享酷炫的东西(查看 NPM 和 GitHub)。
如果您喜欢我所做的工作,并且这个项目帮助您减少了开发时间,请考虑以下操作:
- ★ 收藏并分享您喜欢的(并使用的)项目
- ☕ 给我一杯咖啡 - PayPal.me/duzuns(联系 duzun.me)
- ₿ 在这个地址给我一些 比特币:
bitcoin:3MVaNQocuyRUzUNsTbmzQC8rPUQMC9qafa
(或使用下面的二维码)