使用PHP進行抓取時,您不能只將您在瀏覽器源代碼中看到的內容視爲理所當然。
相反,你首先需要取得與PHP的內容,然後看看源有:
$url = 'http://www.amazon.com/ ... ';
$buffer = file_get_contents($url);
變量$buffer
則包含了你會被刮的HTML。
完成,以你的例子鏈接將顯示,第一和第二地址都具有含可能.priceLarge
元素,你在找什麼:
<span class="priceLarge">$168.00</span>
<b class="priceLarge">$14.99</b>
找出其中的數據是你」之後重新尋找,你可以創建DOM文檔:
$doc = new DOMDocument();
$doc->recover = true;
$saved = libxml_use_internal_errors(true);
$doc->loadHTML($buffer);
您可能也有興趣解析錯誤:
/** @var array|LibXMLError[] $errors */
$errors = libxml_get_errors();
foreach ($errors as $error) {
printf(
"%s: (%d) [%' 3d] #%05d:%' -4d %s\n", get_class($error), $error->level, $error->code, $error->line,
$error->column, rtrim($error->message)
);
}
libxml_use_internal_errors($saved);
因爲這是一種方式,DOMDocument告訴你哪裏出現問題。例如重複的ID值。
加載緩存爲DOM文檔後,您可以創建DOMXPath:
$xp = new DOMXPath($doc);
你會用它來從文檔中獲取的實際值。
例如這兩個例子地址HTML hasshown你正在尋找的信息是包含.listprice
和.priceLarge
的#priceBlock
:
$priceBlock = $doc->getElementById('priceBlock');
printf(
"List Price: %s\nPrice: %s\n"
, $xp->evaluate('string(.//*[@class="listprice"])', $priceBlock)
, $xp->evaluate('string(.//*[@class="priceLarge"])', $priceBlock)
);
這將導致下面的輸出:
List Price: $48.99
Price: $14.99
如果你缺少一些東西,在示例中獲得一個父節段元素作爲$priceBlock
,不僅可以使用Xpath的相對路徑,還可以幫助調試cas Ë你錯過了一些更詳細的信息:
echo $doc->saveHTML($priceBlock);
此輸出整個<div>
包含例如所有定價信息。
如果你設置自己的一些輔助類,你還可以在使用這個獲得從文檔其他有用的信息,刮它,如顯示的價格塊內的所有標籤/職業組合:
// you can find StringCollector at the end of the answer
$tagsWithClass = new StringCollector();
foreach ($xp->evaluate('.//*/@class', $priceBlock) as $class) {
$tagsWithClass->add(sprintf("%s.%s", $class->parentNode->tagName, $class->value));
}
echo $tagsWithClass;
這則輸出收集字符串及其數量的列表,它是這裏的標記名與他們的階級屬性值:
table.product (1)
td.priceBlockLabel (3)
span.listprice (1)
td.priceBlockLabelPrice (1)
b.priceLarge (1)
tr.youSavePriceRow (1)
td.price (1)
正如你所看到的,這是第一個例子URL,因爲.pricelarge
是一個<b>
元素。
這是一個相對簡單的幫手,你可以做更多的事情,比如以樹的形式顯示整個HTML結構。
DomTree::dump($priceBlock);
它會給你下面的輸出,允許的不僅僅是DOMDocument::saveHTML($node)
更好的消費:
`<div id="priceBlock" class="buying">
+"\n\n "
`<table class="product">
+<tr>
| +<td class="priceBlockLabel">
| | `"List Price:"
| +"\n "
| +<td>
| | `<span id="listPriceValue" class="listprice">
| | `"$48.99"
| `"\n "
+<tr id="actualPriceRow">
| +<td id="actualPriceLabel" class="priceBlockLabelPrice">
| | `"Price:"
| +"\n "
| +<td id="actualPriceContent">
| | +<span id="actualPriceValue">
| | | `<b class="priceLarge">
| | | `"$14.99"
| | +"\n "
| | `<span id="actualPriceExtraMessaging">
| | +"\n \n\n\n "
| | +<span>
| | | `"\n \n "
| | +"\n \n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n \n\n\n\n\n& "
| | +<b>
| | | `"FREE Shipping"
| | +" on orders over $35.\n\n\n\n"
| | +<a href="/gp/help/customer/display.html/ref=mk_sss_dp_1/191-4381493-1931545?ie=UTF8&no...">
| | | `"Details"
| | `"\n\n\n\n\n\n\n\n\n \n\n \n \n\n\n\n\n\n \n"
| `"\n"
+<tr id="dealPriceRow">
| +<td id="dealPriceLabel" class="priceBlockLabel">
| | `"Deal Price: "
| +"\n "
| +<td id="dealPriceContent">
| | +"\n "
| | +<span id="dealPriceValue">
| | +"\n "
| | +<span id="dealPriceExtraMessaging">
| | `"\n "
| `"\n"
+<script>
| `[XML_CDATA_SECTION_NODE (4)]
+<tr id="youSaveRow" class="youSavePriceRow">
| +<td id="youSaveLabel" class="priceBlockLabel">
| | `"You Save:"
| +"\n "
| +<td id="youSaveContent" class="price">
| | +<span id="youSaveValue">
| | | `"$34.00\n (69%)"
| | `"\n "
| `"\n "
`<tr>
+<td>
`<td>
`<span>
`"o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o..."
你可以找到它在an answer to Debug a DOMDocument Object in PHP和another one引用。 code is available on github as a gist。
的StringCollector輔助類
/**
* Class StringCollector
*
* Collect strings and count them
*/
class StringCollector implements IteratorAggregate
{
private $array;
public function add($string)
{
$entry = & $this->array[$string];
$entry++;
}
public function getIterator()
{
return new ArrayIterator($this->array);
}
public function __toString()
{
$buffer = '';
foreach ($this as $string => $count) {
$buffer .= sprintf("%s (%d)\n", $string, $count);
}
return $buffer;
}
}
可能是因爲你的瀏覽器中的網頁是一個不同的佈局,則一個在你的PHP – pguardiario 2014-10-12 03:54:53
第一個路徑表達式是正確的,並會產生價格 - 也就是說,如果它正確地應用於數據。 PLease顯示PHP代碼(對於這兩種表達式)。 – 2014-10-12 09:28:08