Можете ли вы привести примеры парсинга HTML? - PullRequest
69 голосов
/ 21 апреля 2009

Как вы анализируете HTML с различными языками и библиотеками разбора?


При ответе:

Отдельные комментарии будут связаны с ответами на вопросы о том, как анализировать HTML с регулярными выражениями, чтобы показать правильный способ выполнения действий.

Ради согласованности я прошу, чтобы в примере был проанализирован HTML-файл для href в тегах привязки. Чтобы облегчить поиск по этому вопросу, я прошу вас придерживаться этого формата

Язык: [название языка]

Библиотека: [имя библиотеки]

[example code]

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

Цель: [что делает анализ]

Ответы [ 29 ]

8 голосов
/ 22 апреля 2009

Язык: Ruby
Библиотека: Нокогири

#!/usr/bin/env ruby
require 'nokogiri'
require 'open-uri'

document = Nokogiri::HTML(open("http://google.com"))
document.css("html head title").first.content
=> "Google"
document.xpath("//title").first.content
=> "Google"
6 голосов
/ 05 марта 2010

Язык: Clojure
Библиотека: Enlive (система шаблонов и трансформаций на основе селектора (в стиле CSS) для Clojure)


Селекторное выражение:

(def test-select
     (html/select (html/html-resource (java.io.StringReader. test-html)) [:a]))

Теперь мы можем сделать следующее в REPL (я добавил разрывы строк в test-select):

user> test-select
({:tag :a, :attrs {:href "http://foo.com/"}, :content ["foo"]}
 {:tag :a, :attrs {:href "http://bar.com/"}, :content ["bar"]}
 {:tag :a, :attrs {:href "http://baz.com/"}, :content ["baz"]})
user> (map #(get-in % [:attrs :href]) test-select)
("http://foo.com/" "http://bar.com/" "http://baz.com/")

Вам понадобится следующее, чтобы попробовать это:

Преамбула:

(require '[net.cgrand.enlive-html :as html])

Тест HTML:

(def test-html
     (apply str (concat ["<html><body>"]
                        (for [link ["foo" "bar" "baz"]]
                          (str "<a href=\"http://" link ".com/\">" link "</a>"))
                        ["</body></html>"])))
5 голосов
/ 21 апреля 2009
5 голосов
/ 22 апреля 2009

Язык: Java
Библиотеки: XOM , TagSoup

Я включил в этот пример намеренно искаженный и непоследовательный XML.

import java.io.IOException;

import nu.xom.Builder;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Node;
import nu.xom.Nodes;
import nu.xom.ParsingException;
import nu.xom.ValidityException;

import org.ccil.cowan.tagsoup.Parser;
import org.xml.sax.SAXException;

public class HtmlTest {
    public static void main(final String[] args) throws SAXException, ValidityException, ParsingException, IOException {
        final Parser parser = new Parser();
        parser.setFeature(Parser.namespacesFeature, false);
        final Builder builder = new Builder(parser);
        final Document document = builder.build("<html><body><ul><li><a href=\"http://google.com\">google</li><li><a HREF=\"http://reddit.org\" target=\"_blank\">reddit</a></li><li><a name=\"nothing\">nothing</a><li></ul></body></html>", null);
        final Element root = document.getRootElement();
        final Nodes links = root.query("//a[@href]");
        for (int linkNumber = 0; linkNumber < links.size(); ++linkNumber) {
            final Node node = links.get(linkNumber);
            System.out.println(((Element) node).getAttributeValue("href"));
        }
    }
}

TagSoup добавляет в документ пространство имен XML, ссылающееся на XHTML, по умолчанию. Я решил подавить это в этом примере. Использование поведения по умолчанию потребует вызова root.query для включения пространства имен, например:

root.query("//xhtml:a[@href]", new nu.xom.XPathContext("xhtml", root.getNamespaceURI())
5 голосов
/ 21 апреля 2009

язык: Perl
библиотека: XML :: Twig

#!/usr/bin/perl
use strict;
use warnings;
use Encode ':all';

use LWP::Simple;
use XML::Twig;

#my $url = '/425063/mozhete-li-vy-privesti-primery-parsinga-html';
my $url = 'http://www.google.com';
my $content = get($url);
die "Couldn't fetch!" unless defined $content;

my $twig = XML::Twig->new();
$twig->parse_html($content);

my @hrefs = map {
    $_->att('href');
} $twig->get_xpath('//*[@href]');

print "$_\n" for @hrefs;

предостережение: может иметь ошибки с широкими символами на страницах, подобных этой (замена URL на закомментированную приведет к получению этой ошибки), но приведенное выше решение HTML :: Parser не разделяет эту проблему.

4 голосов
/ 21 апреля 2009

Язык: C #
Библиотека: System.XML (стандарт .NET)

using System.Collections.Generic;
using System.Xml;

public static void Main(string[] args)
{
    List<string> matches = new List<string>();

    XmlDocument xd = new XmlDocument();
    xd.LoadXml("<html>...</html>");

    FindHrefs(xd.FirstChild, matches);
}

static void FindHrefs(XmlNode xn, List<string> matches)
{
    if (xn.Attributes != null && xn.Attributes["href"] != null)
        matches.Add(xn.Attributes["href"].InnerXml);

    foreach (XmlNode child in xn.ChildNodes)
        FindHrefs(child, matches);
}
4 голосов
/ 21 апреля 2009

Язык: JavaScript
Библиотека: DOM

var links = document.links;
for(var i in links){
    var href = links[i].href;
    if(href != null) console.debug(href);
}

(используя firebug console.debug для вывода ...)

4 голосов
/ 06 октября 2011

Язык: Ракетка

Библиотека: (планета ashinn / html-парсер: 1) и (планета клеммент / sxml2: 1)

(require net/url
         (planet ashinn/html-parser:1)
         (planet clements/sxml2:1))

(define the-url (string->url "http://stackoverflow.com/"))
(define doc (call/input-url the-url get-pure-port html->sxml))
(define links ((sxpath "//a/@href/text()") doc))

Приведенный выше пример использования пакетов из новой системы пакетов: html-анализ и sxml

(require net/url
         html-parsing
         sxml)

(define the-url (string->url "http://stackoverflow.com/"))
(define doc (call/input-url the-url get-pure-port html->xexp))
(define links ((sxpath "//a/@href/text()") doc))

Примечание. Установите необходимые пакеты с помощью команды 'raco' из командной строки с помощью:

raco pkg install html-parsing

и

raco pkg install sxml
3 голосов
/ 22 апреля 2009

Язык: PHP
Библиотека: SimpleXML (и DOM)

<?php
$page = new DOMDocument();
$page->strictErrorChecking = false;
$page->loadHTMLFile('http://stackoverflow.com/questions/773340');
$xml = simplexml_import_dom($page);

$links = $xml->xpath('//a[@href]');
foreach($links as $link)
    echo $link['href']."\n";
3 голосов
/ 22 апреля 2009

Язык: Perl
Библиотека: HTML :: TreeBuilder

use strict;
use HTML::TreeBuilder;
use LWP::Simple;

my $content = get 'http://www.stackoverflow.com';
my $document = HTML::TreeBuilder->new->parse($content)->eof;

for my $a ($document->find('a')) {
    print $a->attr('href'), "\n" if $a->attr('href');
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...