@neliudov
Имярек

Как обойти пустую ноду в SymfonyDomCrawler?

Всем привет. Возникла задача распарсить популярный сайт www.medium.com. Если кто сидел или сидит там, то наверняка замечали, что под каждой статьёй есть количество хлопков. Задача состоит в том, чтобы получить заголовки статей, ссылки на них и количество хлопков под ними для будущей аналитики роста статей. Покопавшись в разметке, я заметил, что теги количества хлопков есть тогда, когда есть само количество. Другими словами, если никто не хлопнул, то там пусто -- нет разметки. Вот тут мой парсер (который, к слову, я пишу при помощи Symfony DomCrawler) и спотыкается.

Вот код:

public function saveData($url)
    {
        $client = new Client();
        $result = $client->request('GET', $url);
        $html = '' . $result->getBody();
        $crawler = new Crawler($html);
        $this->configs = require 'configs.php';
        if (!empty($this)) {
            $this->database = new Database($this->configs['db']);
        }
        if (!empty($crawler)) {
            $crawler->filter('div[class="postArticle postArticle--short js-postArticle js-trackedPost"]')->each(function (Crawler $node, $i) {
                $title = $node->filter('h3')->text();
                $link = $node->filter('a[data-action="open-post"]')->attr('href');
                $star = !empty($rate = $node->filter('button[data-action="show-recommends"]')) ? $rate->text() : 0;
                if (!empty($this->database)) {
                    $this->database->query("INSERT INTO programming (title, link, rate) VALUES (:title, :link, :rate)", [
                       'title' => $title,
                       'link' => $link,
                       'rate' => (int)$star
                    ]);
                }
            });
        }
    }


Я не могу понять, как обработать ноду, если разметки нет. Сейчас выводится ошибка The current node list is empty. Я хочу присвоить рейтинг этой статьи нулю, если разметки нет, что логично. Но не могу понять, как это сделать. Та логика, что сейчас, не работает.
  • Вопрос задан
  • 1197 просмотров
Решения вопроса 1
VlastV
@VlastV
Ведущий разработчик – практик
$node->filter возвращает Crawler, у него есть метод count() который возвращает количество node.
Соответственно, вам после $node->filter(...), надо проверить количество

$recommends = $node->filter('button[data-action="show-recommends"]');
$rate = $recommends->count() ? $recomments->text() : 0;
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы