php使用pthreads v3多線程實(shí)現(xiàn)抓取新浪新聞信息操作示例
本文實(shí)例講述了php使用pthreads v3多線程實(shí)現(xiàn)抓取新浪新聞信息。分享給大家供大家參考,具體如下:
我們使用pthreads,來寫一個(gè)多線程的抓取頁面小程序,把結(jié)果存到數(shù)據(jù)庫(kù)里。
數(shù)據(jù)表結(jié)構(gòu)如下:
CREATE TABLE `tb_sina` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', `url` varchar(256) DEFAULT '' COMMENT 'url地址', `title` varchar(128) DEFAULT '' COMMENT '標(biāo)題', `time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '時(shí)間', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='sina新聞';
代碼如下:
<?php
class DB extends Worker
{
private static $db;
private $dsn;
private $root;
private $pwd;
public function __construct($dsn, $root, $pwd)
{
$this->dsn = $dsn;
$this->root = $root;
$this->pwd = $pwd;
}
public function run()
{
//創(chuàng)建連接對(duì)象
self::$db = new PDO($this->dsn, $this->root, $this->pwd);
//把require放到worker線程中,不要放到主線程中,不然會(huì)報(bào)錯(cuò)找不到類
require './vendor/autoload.php';
}
//返回一個(gè)連接資源
public function getConn()
{
return self::$db;
}
}
class Sina extends Thread
{
private $name;
private $url;
public function __construct($name, $url)
{
$this->name = $name;
$this->url = $url;
}
public function run()
{
$db = $this->worker->getConn();
if (empty($db) || empty($this->url)) {
return false;
}
$content = file_get_contents($this->url);
if (!empty($content)) {
//獲取標(biāo)題,地址,時(shí)間
$data = QL\QueryList::Query($content, [
'tit' => ['.c_tit > a', 'text'],
'url' => ['.c_tit > a', 'href'],
'time' => ['.c_time', 'text'],
], '', 'UTF-8', 'GB2312')->getData();
//把獲取的數(shù)據(jù)插入數(shù)據(jù)庫(kù)
if (!empty($data)) {
$sql = 'INSERT INTO tb_sina(`url`, `title`, `time`) VALUES';
foreach ($data as $row) {
//修改下時(shí)間,新浪的時(shí)間格式是這樣的04-23 15:30
$time = date('Y') . '-' . $row['time'] . ':00';
$sql .= "('{$row['url']}', '{$row['tit']}', '{$time}'),";
}
$sql = rtrim($sql, ',');
$ret = $db->exec($sql);
if ($ret !== false) {
echo "線程{$this->name}成功插入{$ret}條數(shù)據(jù)\n";
} else {
var_dump($db->errorInfo());
}
}
}
}
}
//抓取頁面地址
$url = 'http://roll.news.sina.com.cn/s/channel.php?ch=01#col=89&spec=&type=&ch=01&k=&offset_page=0&offset_num=0&num=60&asc=&page=';
//創(chuàng)建pool池
$pool = new Pool(5, 'DB', ['mysql:dbname=test;host=192.168.33.226', 'root', '']);
//獲取100個(gè)分頁數(shù)據(jù)
for ($ix = 1; $ix <= 100; $ix++) {
$pool->submit(new Sina($ix, $url . $ix));
}
//循環(huán)收集垃圾,阻塞主線程,等待子線程結(jié)束
while ($pool->collect()) ;
$pool->shutdown();
由于使用到了QueryList,大家可以通過composer進(jìn)行安裝。
composer require jaeger/querylist
不過安裝的版本是3.2,在我的php7.2下會(huì)有問題,由于each()已經(jīng)被廢棄,所以修改下源碼,each()全換成foreach()就好了。
運(yùn)行結(jié)果如下:

數(shù)據(jù)也保存進(jìn)了數(shù)據(jù)庫(kù)

當(dāng)然大家也可以再次通過url,拿到具體的頁面內(nèi)容,這里就不做演示了,有興趣的可以自已去實(shí)現(xiàn)。
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《PHP進(jìn)程與線程操作技巧總結(jié)》、《PHP網(wǎng)絡(luò)編程技巧總結(jié)》、《PHP基本語法入門教程》、《PHP數(shù)組(Array)操作技巧大全》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫(kù)操作入門教程》及《php常見數(shù)據(jù)庫(kù)操作技巧匯總》
希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。
相關(guān)文章
PHP實(shí)現(xiàn)的oracle分頁函數(shù)實(shí)例
這篇文章主要介紹了PHP實(shí)現(xiàn)的oracle分頁函數(shù),結(jié)合實(shí)例形式分析了PHP針對(duì)oracle數(shù)據(jù)庫(kù)使用rownum代替MySQL中l(wèi)imit實(shí)現(xiàn)的分頁操作相關(guān)技巧,需要的朋友可以參考下2016-01-01
php實(shí)現(xiàn)把數(shù)組按指定的個(gè)數(shù)分隔
這篇文章主要介紹了php實(shí)現(xiàn)把數(shù)組按指定的個(gè)數(shù)分隔。需要的朋友可以過來參考下,希望對(duì)大家有所幫助2014-02-02
PHP按指定鍵值對(duì)二維數(shù)組進(jìn)行排序的方法
這篇文章主要介紹了PHP按指定鍵值對(duì)二維數(shù)組進(jìn)行排序的方法,涉及PHP二維數(shù)組的遍歷及array_multisort函數(shù)的使用技巧,需要的朋友可以參考下2015-12-12
PHP 下載文件時(shí)自動(dòng)添加bom頭的方法實(shí)例
這篇文章主要介紹了PHP 下載文件時(shí)自動(dòng)添加bom頭的方法實(shí)例,有需要的朋友可以參考一下2014-01-01
PHP實(shí)現(xiàn)在windows下配置sendmail并通過mail()函數(shù)發(fā)送郵件的方法
這篇文章主要介紹了PHP實(shí)現(xiàn)在windows下配置sendmail并通過mail()函數(shù)發(fā)送郵件的方法,較為詳細(xì)的分析了Windows平臺(tái)sendmail配置步驟與相應(yīng)的使用技巧,需要的朋友可以參考下2017-06-06

