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

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


При ответе:

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

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

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

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

[example code]

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

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

Ответы [ 29 ]

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

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

$.each($('a[href]'), function(){
    console.debug(this.href);
});

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

И загрузка любой html-страницы:

$.get('http://stackoverflow.com/', function(page){
     $(page).find('a[href]').each(function(){
        console.debug(this.href);
    });
});

Использовал еще одну функцию для каждой, я думаю, что она чище при использовании методов цепочки.

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

Язык: C #
Библиотека: HtmlAgilityPack

class Program
{
    static void Main(string[] args)
    {
        var web = new HtmlWeb();
        var doc = web.Load("http://www.stackoverflow.com");

        var nodes = doc.DocumentNode.SelectNodes("//a[@href]");

        foreach (var node in nodes)
        {
            Console.WriteLine(node.InnerHtml);
        }
    }
}
22 голосов
/ 21 апреля 2009

язык: Python
библиотека: BeautifulSoup

from BeautifulSoup import BeautifulSoup

html = "<html><body>"
for link in ("foo", "bar", "baz"):
    html += '<a href="http://%s.com">%s</a>' % (link, link)
html += "</body></html>"

soup = BeautifulSoup(html)
links = soup.findAll('a', href=True) # find <a> with a defined href attribute
print links  

Выход:

[<a href="http://foo.com">foo</a>,
 <a href="http://bar.com">bar</a>,
 <a href="http://baz.com">baz</a>]

также возможно:

for link in links:
    print link['href']

выход:

http://foo.com
http://bar.com
http://baz.com
20 голосов
/ 22 апреля 2009

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

use strict;
use warnings;
use pQuery;

my $html = join '',
    "<html><body>",
    (map { qq(<a href="http://$_.com">$_</a>) } qw/foo bar baz/),
    "</body></html>";

pQuery( $html )->find( 'a' )->each(
    sub {  
        my $at = $_->getAttribute( 'href' ); 
        print "$at\n" if defined $at;
    }
);
15 голосов
/ 21 апреля 2009

язык: оболочка
библиотека: lynx (ну, это не библиотека, но в оболочке каждая программа является своего рода библиотекой)

lynx -dump -listonly http://news.google.com/
14 голосов
/ 21 апреля 2009

язык: Ruby
библиотека: Hpricot

#!/usr/bin/ruby

require 'hpricot'

html = '<html><body>'
['foo', 'bar', 'baz'].each {|link| html += "<a href=\"http://#{link}.com\">#{link}</a>" }
html += '</body></html>'

doc = Hpricot(html)
doc.search('//a').each {|elm| puts elm.attributes['href'] }
12 голосов
/ 21 апреля 2009

язык: Python
библиотека: HTMLParser

#!/usr/bin/python

from HTMLParser import HTMLParser

class FindLinks(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)

    def handle_starttag(self, tag, attrs):
        at = dict(attrs)
        if tag == 'a' and 'href' in at:
            print at['href']


find = FindLinks()

html = "<html><body>"
for link in ("foo", "bar", "baz"):
    html += '<a href="http://%s.com">%s</a>' % (link, link)
html += "</body></html>"

find.feed(html)
11 голосов
/ 21 апреля 2009

язык: Perl
библиотека: HTML :: Parser

#!/usr/bin/perl

use strict;
use warnings;

use HTML::Parser;

my $find_links = HTML::Parser->new(
    start_h => [
        sub {
            my ($tag, $attr) = @_;
            if ($tag eq 'a' and exists $attr->{href}) {
                print "$attr->{href}\n";
            }
        }, 
        "tag, attr"
    ]
);

my $html = join '',
    "<html><body>",
    (map { qq(<a href="http://$_.com">$_</a>) } qw/foo bar baz/),
    "</body></html>";

$find_links->parse($html);
9 голосов
/ 21 апреля 2009

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

Прелесть Perl в том, что у вас есть модули для очень специфических задач. Как извлечение ссылки.

Вся программа:

#!/usr/bin/perl -w
use strict;

use HTML::LinkExtor;
use LWP::Simple;

my $url     = 'http://www.google.com/';
my $content = get( $url );

my $p       = HTML::LinkExtor->new( \&process_link, $url, );
$p->parse( $content );

exit;

sub process_link {
    my ( $tag, %attr ) = @_;

    return unless $tag eq 'a';
    return unless defined $attr{ 'href' };

    print "- $attr{'href'}\n";
    return;
}

Пояснение:

  • Использовать строгий - включает «строгий» режим - облегчает потенциальную отладку, не полностью отношение к примеру
  • использовать HTML :: LinkExtor - загрузка интересного модуля
  • используйте LWP :: Simple - простой способ получить html для тестов
  • my $ url = 'http://www.google.com/' - с какой страницы мы будем извлекать URL-адреса из
  • my $ content = get ($ url) - извлекает страницу html
  • my $ p = HTML :: LinkExtor-> new (\ & process_link, $ url) - создает объект LinkExtor, предоставляя ему ссылку на функцию, которая будет использоваться как обратный вызов для каждого URL, и $ url для использования в качестве BASEURL для относительного URLs
  • $ p-> parse ($ content) - я думаю, довольно очевидно
  • выход - конец программы
  • sub process_link - начало функции process_link
  • my ($ tag,% attr) - получить аргументы, которые представляют собой имя тега и его атрибуты
  • возврат, если $ tag eq 'a' - пропустить обработку, если тег не
  • вернуть, если не поврежден $ attr {'href'} - пропустить обработку, если тег не имеет атрибута href
  • print "- $ attr {'href'} \ n"; - довольно очевидно, я думаю:)
  • возвращение; - закончить функцию

Вот и все.

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

Язык: Common Lisp
Библиотека: Закрытие Html , Закрытие Xml , CL-WHO

(показано с использованием DOM API, без использования XPATH или STP API)

(defvar *html*
  (who:with-html-output-to-string (stream)
    (:html
     (:body (loop
               for site in (list "foo" "bar" "baz")
               do (who:htm (:a :href (format nil "http://~A.com/" site))))))))

(defvar *dom*
  (chtml:parse *html* (cxml-dom:make-dom-builder)))

(loop
   for tag across (dom:get-elements-by-tag-name *dom* "a")
   collect (dom:get-attribute tag "href"))
=> 
("http://foo.com/" "http://bar.com/" "http://baz.com/")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...