Programing

HTML 구문 분석의 예를 제공 할 수 있습니까?

lottogame 2020. 11. 3. 07:37
반응형

HTML 구문 분석의 예를 제공 할 수 있습니까?


다양한 언어 및 구문 분석 라이브러리로 HTML을 어떻게 구문 분석합니까?


답변 할 때 :

작업을 수행하는 올바른 방법을 보여주는 방법으로 정규식을 사용하여 HTML을 구문 분석하는 방법에 대한 질문에 대한 답변에 개별 의견이 연결됩니다.

일관성을 위해 hrefin anchor 태그에 대한 HTML 파일을 구문 분석하는 예제를 요청 합니다. 이 질문을 쉽게 검색 할 수 있도록이 형식을 따르시기 바랍니다.

언어 : [언어 이름]

라이브러리 : [라이브러리 이름]

[example code]

라이브러리를 라이브러리 문서에 대한 링크로 만드십시오. 링크 추출 이외의 예를 제공하려면 다음을 포함하십시오.

목적 : [파싱이 수행하는 작업]


언어 : 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);
    });
});

이것에 대해 다른 각 기능을 사용했는데 메소드를 연결할 때 더 깨끗하다고 ​​생각합니다.


언어 : 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);
        }
    }
}

언어 : 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

언어 : 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;
    }
);

언어 : 쉘
라이브러리 : lynx (글쎄요, 그것은 라이브러리가 아니지만 쉘에서는 모든 프로그램이 일종의 라이브러리입니다)

lynx -dump -listonly http://news.google.com/

언어 : 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'] }

언어 : 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)

언어 : 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);

언어 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로 사용할 $ url
  • $ p-> parse ($ content)-꽤 분명합니다.
  • 종료-프로그램 종료
  • sub process_link-process_link 기능 시작
  • my ($ tag, % attr)-태그 이름 및 속성 인 인수 가져 오기
  • $ tag eq 'a'가 아니면 반환-태그가 <a>가 아니면 처리를 건너 뜁니다.
  • 무효화되지 않은 경우 반환 $ attr { 'href'}-<a> 태그에 href 속성이없는 경우 처리를 건너 뜁니다.
  • print "-$ attr { 'href'} \ n"; -꽤 명백한 것 같아요 :)
  • 반환; -기능 완료

그게 다야.


언어 : 루비
도서관 : 노코 기리

#!/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"

언어 : Common Lisp
라이브러리 : Closure Html , Closure Xml , CL-WHO

(XPATH 또는 STP API를 사용하지 않고 DOM 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/")

언어 : Clojure
라이브러리 : Enlive ( Clojure를 위한 선택기 기반 (CSS) 템플릿 및 변환 시스템)


선택기 표현식 :

(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>"])))

언어 : 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을 주석 처리 된 URL로 변경하면이 오류가 발생합니다) 위의 HTML :: Parser 솔루션은이 문제를 공유하지 않습니다.


언어 : Perl
라이브러리 : HTML :: Parser
목적 : Perl 정규식으로 사용하지 않는 중첩 된 HTML 스팬 태그를 제거하려면 어떻게해야합니까?


언어 : 자바
라이브러리 : 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은 기본적으로 XHTML을 참조하는 XML 네임 스페이스를 문서에 추가합니다. 이 샘플에서는이를 억제하도록 선택했습니다. 기본 동작을 사용하려면 root.query다음과 같은 네임 스페이스를 포함 하도록 호출해야합니다 .

root.query("//xhtml:a[@href]", new nu.xom.XPathContext("xhtml", root.getNamespaceURI())

언어 : 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);
}

언어 : 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 사용 ...)


언어 : 라켓

라이브러리 : (planet ashinn / html-parser : 1)(planet clements / 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-parsingsxml

(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

언어 : Python
라이브러리 : 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에는 DOM을 순회하기위한 CSS 선택기 클래스도있어 JQuery를 사용하는 것과 매우 유사하게 사용할 수 있습니다.

for a in tree.cssselect('a[href]'):
    print a.get('href')

언어 : 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";

언어 : Objective-C
라이브러리 : libxml2 + Matt Gallagher의 libxml2 래퍼 + Ben Copsey의 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;
}

언어 : 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');
}

언어 : Python
라이브러리 : HTQL

import htql; 

page="<a href=a.html>1</a><a href=b.html>2</a><a href=c.html>3</a>";
query="<a>:href,tx";

for url, text in htql.HTQL(page, query): 
    print url, text;

간단하고 직관적입니다.


언어 : Ruby
라이브러리 : Nokogiri

#!/usr/bin/env ruby

require "nokogiri"
require "open-uri"

doc = Nokogiri::HTML(open('http://www.example.com'))
hrefs = doc.search('a').map{ |n| n['href'] }

puts hrefs

출력되는 내용 :

/
/domains/
/numbers/
/protocols/
/about/
/go/rfc2606
/about/
/about/presentations/
/about/performance/
/reports/
/domains/
/domains/root/
/domains/int/
/domains/arpa/
/domains/idn-tables/
/protocols/
/numbers/
/abuse/
http://www.icann.org/
mailto:iana@iana.org?subject=General%20website%20feedback

이것은 위의 작은 회전으로 보고서에 사용할 수있는 출력을 생성합니다. href 목록의 첫 번째 요소와 마지막 요소 만 반환합니다.

#!/usr/bin/env ruby

require "nokogiri"
require "open-uri"

doc = Nokogiri::HTML(open('http://nokogiri.org'))
hrefs = doc.search('a[href]').map{ |n| n['href'] }

puts hrefs
  .each_with_index                     # add an array index
  .minmax{ |a,b| a.last <=> b.last }   # find the first and last element
  .map{ |h,i| '%3d %s' % [1 + i, h ] } # format the output

  1 http://github.com/tenderlove/nokogiri
100 http://yokolet.blogspot.com

언어 : 자바
라이브러리 : jsoup

import java.io.IOException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.xml.sax.SAXException;

public class HtmlTest {
    public static void main(final String[] args) throws SAXException, ValidityException, ParsingException, IOException {
        final Document document = Jsoup.parse("<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>");
        final Elements links = document.select("a[href]");
        for (final Element element : links) {
            System.out.println(element.attr("href"));
        }
    }
}

언어 : PHP 라이브러리 : DOM

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

$links = $xpath->query('//a[@href]');
for ($i = 0; $i < $links->length; $i++)
    echo $links->item($i)->getAttribute('href'), "\n";

때로는 잘못된 html 구문 분석 경고를 억제 @하기 $doc->loadHTMLFile위해 기호 를 삽입하는 것이 유용합니다.


phantomjs를 사용하여이 파일을 extract-links.js로 저장하십시오.

var page = new WebPage(),
    url = 'http://www.udacity.com';

page.open(url, function (status) {
    if (status !== 'success') {
        console.log('Unable to access network');
    } else {
        var results = page.evaluate(function() {
            var list = document.querySelectorAll('a'), links = [], i;
            for (i = 0; i < list.length; i++) {
                links.push(list[i].href);
            }
            return links;
        });
        console.log(results.join('\n'));
    }
    phantom.exit();
});

운영:

$ ../path/to/bin/phantomjs extract-links.js

언어 : Coldfusion 9.0.1+

라이브러리 : jSoup

<cfscript>
function parseURL(required string url){
var res = [];
var javaLoader = createObject("javaloader.JavaLoader").init([expandPath("./jsoup-1.7.3.jar")]);
var jSoupClass = javaLoader.create("org.jsoup.Jsoup");
//var dom = jSoupClass.parse(html); // if you already have some html to parse.
var dom = jSoupClass.connect( arguments.url ).get();
var links = dom.select("a");
for(var a=1;a LT arrayLen(links);a++){
    var s={};s.href= links[a].attr('href'); s.text= links[a].text(); 
    if(s.href contains "http://" || s.href contains "https://") arrayAppend(res,s); 
}
return res; 
}   

//writeoutput(writedump(parseURL(url)));
</cfscript>
<cfdump var="#parseURL("http://stackoverflow.com/questions/773340/can-you-provide-examples-of-parsing-html")#">

구조체의 배열을 반환하며 각 구조체에는 HREF 및 TEXT 개체가 포함됩니다.


언어 : JavaScript / Node.js

라이브러리 : 요청Cheerio

var request = require('request');
var cheerio = require('cheerio');

var url = "https://news.ycombinator.com/";
request(url, function (error, response, html) {
    if (!error && response.statusCode == 200) {
        var $ = cheerio.load(html);
        var anchorTags = $('a');

        anchorTags.each(function(i,element){
            console.log(element["attribs"]["href"]);
        });
    }
});

요청 라이브러리는 html 문서를 다운로드하고 Cheerio를 사용하면 jquery css 선택기를 사용하여 html 문서를 대상으로 지정할 수 있습니다.

참고 URL : https://stackoverflow.com/questions/773340/can-you-provide-examples-of-parsing-html

반응형