среда, 11 марта 2009 г.

парсер yandex.market.ru

Как я и обещал немного поделюсь рецептом создания парсера yandex.market.ru и вообще HTML страничек. Все дело в XPath, если его осилить, то парсить можно практические любые ресурсы, огромное спасибо автору данного ресурса, где на примерах подробно описана работа XPath вне зависимости от языка программирования.

Привожу пример XPath для парсинга yandex.market.ru, точнее подробного описания товара:

1. XPath для названия характеристики товара:
"//div[@id='full-spec-cont']/table/tbody/tr/td[@class=\'label\']/span"

2. XPath для содержимого характеристики товара:
"//div[@id='full-spec-cont']/table/tbody/tr/td[@class=\'label\']/following-sibling::*"

С таким же успехом парситься краткая характеристика товара, его название, маленькое и большое изображение. Вообще для граббера страничек я использовал Sgml Reader, в отличие от других парсеров HTML все сводится к написанию вышеупомянутого XPath.

Будем к примеру парсить следующую страничку (это разумеется кусок кода полученной странички):

<div style="display: none;" id="full-spec-cont">
<img class="b-banish" src="http://clck.yandex.ru/click/dtype=stred/pid=47/cid=2073/*http://market.yandex.ru/i/edot.gif"><table border="0" width="48%" cellspacing="0" cellpadding="5" class="modelProperties">
<colgroup span="2"></colgroup>
<tbody>
<tr><td colspan="2" class="title"><b>Основные характеристики</b></td></tr>
<tr>
<td class="label"><span>Тип</span></td>
<td>ЖК-телевизор</td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td class="label"><span>Встроенный DVD-плеер</span></td>
<td>есть</td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>

Здесь "Тип" и "Встроенный DVD-плеер" - это название характеристики товара, а "ЖК-телевизор" и "есть" - содержимое характеристики товара.
Я не буду вдаваться в подробности работы XPath, но есть возможность парсить не отдельные названия характеристик и описание товара, а целиком полное или краткое описание товара в табличном виде, как оно представлено на yandex.market.ru.

Пример кода:
//название характеристики товара (полное описание товара)
string xpathExpressionNopis = ("//div[@id='full-spec-cont']/table/tbody/tr/td[@class=\'label\']/span");
//описание характеристики товара(полное описание товара)
string xpathExpressionOpis = ("//div[@id='full-spec-cont']/table/tbody/tr/td[@class=\'label\']/following-sibling::*");
//Получаем текст старницы:
WebClient client = new WebClient();
string Msg;
//Для примера взят BBK LD1506K, сюда вставляется свой искомый товар
Msg = client.DownloadString("http://market.yandex.ru/search.xml?cvredirect=1&text=BBK LD1506K");
//Загружаем страницу в XmlDocument:
SgmlReader reader = new SgmlReader();
reader.InputStream = new StringReader(Msg);
XmlDocument document = new XhtmlDocument(reader.NameTable);
document.Load(reader);
//ищем все ноды с названием характеристики товара
XmlNodeList nodeNopis = document.SelectNodes(xpathExpressionNopis);
//поиск нод с описанием характеристик товара
//XmlNodeList nodeOpis = document.SelectNodes(xpathExpressionOpis);
//Далее делаем с содержимым нод что необходимо...

Естественно весь этот код необходимо заключить в тело цикла, для перебора всего списка искомых товаров, а так же предусмотреть возможность перехвата исключений с помощью try и catch.