Можно ли обеспечить примеры парсинга HTML?

Рабочий пример объединения осей в одном xpath может быть:

//*[following-sibling::*[@class="bottom-notice"] and preceding-sibling::*[@name="new-answer"]]

Он ищет элемент form, чтобы написать ответ на этой странице.

69
задан 10 revs, 4 users 70% 22 March 2013 в 20:24
поделиться

21 ответ

Язык: 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);
    });
});

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

29
ответ дан 24 November 2019 в 13:36
поделиться

Язык: 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
ответ дан 24 November 2019 в 13:36
поделиться

Язык: 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
ответ дан 24 November 2019 в 13:36
поделиться

Язык: 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);
        }
    }
}
25
ответ дан 24 November 2019 в 13:36
поделиться

Язык: 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');
}
3
ответ дан 24 November 2019 в 13:36
поделиться

Language: Objective-C
Library: libxml2 + Matt Gallagher's libxml2 wrappers + Ben Copsey's ASIHTTPRequest

ASIHTTPRequest *request = [ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://stackoverflow.com/questions/773340"];
[request start];
NSError *error = [request error];
if (!error) {
    NSData *response = [request responseData];
    NSLog(@"Data: %@", [[self query:@"//a[@href]" withResponse:response] description]);
    [request release];
}
else 
    @throw [NSException exceptionWithName:@"kMyHTTPRequestFailed" reason:@"Request failed!" userInfo:nil];

...

- (id) query:(NSString *)xpathQuery WithResponse:(NSData *)resp {
    NSArray *nodes = PerformHTMLXPathQuery(resp, xpathQuery);
    if (nodes != nil)
        return nodes;
    return nil;
}
3
ответ дан 24 November 2019 в 13:36
поделиться

Язык: 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
ответ дан 24 November 2019 в 13:36
поделиться

язык: Python
library: lxml.html

import lxml.html

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

tree = lxml.html.document_fromstring(html)
for element, attribute, link, pos in tree.iterlinks():
    if attribute == "href":
        print link

В lxml также есть класс селектора CSS для обхода DOM, что делает его использование очень похожим на использование JQuery:

for a in tree.cssselect('a[href]'):
    print a.get('href')
3
ответ дан 24 November 2019 в 13:36
поделиться

язык : 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)
12
ответ дан 24 November 2019 в 13:36
поделиться

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

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

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

#my $url = 'http://stackoverflow.com/questions/773340/can-you-provide-an-example-of-parsing-html-with-your-favorite-parser';
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, описанное выше, не ' не могу поделиться этой проблемой.

5
ответ дан 24 November 2019 в 13:36
поделиться

Язык: Common Lisp
Библиотека: Closure Html , Closure 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/")
8
ответ дан 24 November 2019 в 13:36
поделиться

Язык: Ruby
Библиотека: Nokogiri

#!/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"
8
ответ дан 24 November 2019 в 13:36
поделиться

Язык 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;
}

Объяснение:

Вот и все.

9
ответ дан 24 November 2019 в 13:36
поделиться

язык: 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);
11
ответ дан 24 November 2019 в 13:36
поделиться

Язык: 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
ответ дан 24 November 2019 в 13:36
поделиться

язык: 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'] }
14
ответ дан 24 November 2019 в 13:36
поделиться

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

lynx -dump -listonly http://news.google.com/
15
ответ дан 24 November 2019 в 13:36
поделиться

Язык: 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;
    }
);
20
ответ дан 24 November 2019 в 13:36
поделиться

язык: 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
22
ответ дан 24 November 2019 в 13:36
поделиться

Язык: 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>"])))
6
ответ дан 24 November 2019 в 13:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: