【问题标题】:PHP Scraping company data using GuzzlePHP 使用 Guzzle 抓取公司数据
【发布时间】:2015-01-17 22:32:46
【问题描述】:

我正在尝试审核来自 companycheck.co.uk 的大量公司数据,我当前的脚本似乎只从第一页循环了前 10 个结果。我让脚本一次收集了 10 多个结果,但这在大约 600 个结果后导致了致命错误(不是超时错误,而是某种连接错误),我需要脚本更可靠,因为我是获取超过 40,000 个结果。

到目前为止我的代码:

<?php
set_time_limit(0);
ini_set('max_execution_time', 0);

require 'vendor/autoload.php';
require "Guzzle/guzzle.phar";


// Add this to allow your app to use Guzzle and the Cookie Plugin.
use Guzzle\Http\Client as GuzzleClient;
use Guzzle\Plugin\Cookie\Cookie;
use Guzzle\Plugin\Cookie\CookiePlugin;
use Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar;
use Guzzle\Plugin\Cookie\CookieJar\CookieJarInterface;



$Pagesurl  = 'http://companycheck.co.uk/search/UpdateSearchCompany?searchTerm=cars&type=name';
$pagesData = json_decode(file_get_contents($Pagesurl), true);


$resultsFound = $pagesData["hits"]["found"];
$pages        = ceil($resultsFound / 10);
//echo $pages;

echo "<br>";

for ($p = 0; $p < $pages; $p++) {

    $url  = 'http://companycheck.co.uk/search/UpdateSearchCompany?searchTerm=cars&type=name&companyPage=' . $p . '';
    $data = json_decode(file_get_contents($url), true);
    for ($i = 0; $i < 11; $i++) {
        $id             = $data["hits"]["hit"][$i]["id"];
        $TradingAddress = $data["hits"]["hit"][$i]["data"]["address"][0];
        $companyName    = $data["hits"]["hit"][$i]["data"]["companyname"][0];
        $companyNumber  = $data["hits"]["hit"][$i]["data"]["companynumber"][0];

        $finalURL = "http://companycheck.co.uk/company/" . $id . "";


        $httpClient = new GuzzleClient($finalURL);
        $httpClient->setSslVerification(FALSE);

        $cookieJar    = new ArrayCookieJar();
        // Create a new cookie plugin
        $cookiePlugin = new CookiePlugin($cookieJar);
        // Add the cookie plugin to the client
        $httpClient->addSubscriber($cookiePlugin);
        $httpClient->setUserAgent("Opera/9.23 (Windows NT 5.1; U; en-US)");

        $request  = $httpClient->get($finalURL);
        $response = $request->send();

        $body    = $response->getBody(true);
        $matches = array();

        preg_match_all('/<table.*?>(.*?)<\/table>/si', $body, $table);
        preg_match('/<meta name=\"keywords\" content=\"(.*?)\"\/>/si', $body, $metaName);
        preg_match('/<p itemprop="streetAddress".*?>(.*?)<\/p>/si', $body, $regOffice);


        echo "<table><tbody>";

        echo "<tr><th>Company Name</th><td>";
        echo $companyName;
        echo "</td></tr>";

        echo "<tr><th>Company Number</th><td>";
        echo $companyNumber;
        echo "</td></tr>";

        echo "<tr><th>Registar Address</th><td>";
        echo str_replace("<br>", " ", $regOffice[0]);
        echo "</td></tr>

<tr><th>Trading Address</th><td>";
        echo $TradingAddress;
        echo "</td></tr>
<tr>
<th>Director Name</th>
<td>";
        $name = explode(',', $metaName[1]);
        echo $name[2];
        echo "</td>

</tr></tbody></table>";
        echo $table[0][1];
        echo "<br><br><br>";


    }

}

为了获取每个页面,我使用http://companycheck.co.uk/search/UpdateSearchCompany?searchTerm=cars&type=name&companyPage=1 为每个页面从http://companycheck.co.uk/search/results?SearchCompaniesForm[name]=cars&yt1= 和一些数据返回json,但不是全部。

有了这个,我可以获取每个公司的 ID 以导航到每个链接并从网站的前端抓取一些数据。

例如第一个结果是:

"hits":{"found":42842,"start":0,"hit":[{"id":"08958547","data":{"address":["THE ALEXANDER SUITE SILK POINT, QUEENS AVENUE, MACCLESFIELD, SK10 2BB"],"assets":[],"assetsnegative":[],"cashatbank":[],"cashatbanknegative":[],"companyname":["CAR2CARS LIMITED"],"companynumber":["08958547"],"dissolved":["0"],"liabilities":[],"liabilitiesnegative":[],"networth":[],"networthnegative":[],"postcode":["SK10 2BB"],"siccode":[]}}

所以第一个链接是:http://companycheck.co.uk/company/08958547

然后我可以从中提取表数据,例如:

Registered Office

THE ALEXANDER SUITE SILK POINT
QUEENS AVENUE
MACCLESFIELD
SK10 2BB

以及来自元标记的信息,例如:

<meta name="keywords" content="CAR2CARS LIMITED, 08958547,INCWISE COMPANY SECRETARIES LIMITED,MR ROBERT CARTER"/>

返回结果之一的示例:

Company Name    CAR2CARS LIMITED
Company Number  08958547
Registar Address    
THE ALEXANDER SUITE SILK POINT QUEENS AVENUE MACCLESFIELD SK10 2BB

Trading Address THE ALEXANDER SUITE SILK POINT, QUEENS AVENUE, MACCLESFIELD, SK10 2BB
Director Name   INCWISE COMPANY SECRETARIES LIMITED
Telephone   No telephone number available.
Email Address   No email address available.
Contact Person  No contact person available.
Business Activity   No Business Activity on record.

每个 json 页面包含 10 个公司 ID 放入 URL 中以查找公司,我需要从这些公司中的每一个中从完整 URL 中抓取数据,然后在这 10 个之后进入下一页并获取下一个 10 和循环到最后一页。

【问题讨论】:

  • 你最近怎么样?

标签: php guzzle


【解决方案1】:

几乎可以肯定,由于请求数量过多,它会故意阻止您。尝试在请求之间暂停一下——这可能会帮助你避开他们的视线。

您打算抓取的网站似乎是一家私人公司,该公司正在重新格式化和重新发布来自 Companies House 的数据,这是英国公司信息的官方记录。这家公司提供an API,每月允许 10K 请求,这要么免费,要么每月收费 200 英镑,具体取决于您需要的数据。既然你想立即得到 40K 的结果,难怪他们操作 IP 块。

抓取的对错很复杂,但有一点要理解:通过复制别人的数据,您是在试图避免自己整理数据的成本。通过从其他人的服务器上获取它们,您也增加了他们的运营成本而无需报销,这种经济现象被称为externality

在某些情况下,我赞成以这种方式转嫁成本,例如抓取目标参与潜在的市场滥用(例如垄断行为)并且抓取具有缓解作用。听说有些航空公司运营防刮装置,就是不希望价格刮板拉低价格。由于降低价格符合消费者的利益,人们可以争辩说外部性是合理的(基于道德,如果不是法律依据)。

在您的情况下,我建议直接从 Companies House 获取这些数据,因为它可能会以更低的成本获得。无论如何,如果您重新发布从抓取中获得的有价值的数据,并避开了阻止您的技术尝试,您可能会发现自己陷入法律困境。如果有疑问(并且如果没有我之前概述的道德或公共利益辩护),请与网站运营商联系并询问您想要做什么。

【讨论】:

    猜你喜欢
    • 2021-08-02
    • 2018-11-11
    • 2021-02-20
    • 2021-12-18
    • 2017-05-19
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多