1. ホーム
  2. python

[解決済み] BeautifulSoupでXPathは使えるか?

2022-05-31 11:11:13

質問

私はURLをスクレイピングするためにBeautifulSoupを使用しています、私は次のコードを持っていた、見つけるために td タグを見つけ、そのクラスが 'empformbody' :

import urllib
import urllib2
from BeautifulSoup import BeautifulSoup

url =  "http://www.example.com/servlet/av/ResultTemplate=AVResult.html"
req = urllib2.Request(url)
response = urllib2.urlopen(req)
the_page = response.read()
soup = BeautifulSoup(the_page)

soup.findAll('td',attrs={'class':'empformbody'})

さて、上記のコードで findAll を使ってタグとそれに関連する情報を取得することができますが、XPathを使いたいと思います。BeautifulSoupでXPathを使用することは可能でしょうか?もし可能であれば、サンプルコードを教えてください。

どのように解決するのですか?

いいえ、BeautifulSoup単体では、XPath式に対応していません。

代替のライブラリです。 lxml , は XPath 1.0 をサポートしています。これには BeautifulSoup互換モード があり、壊れた HTML を Soup と同じようにパースしようとします。しかし デフォルトの lxml HTML パーサー は壊れた HTML をパースするのにちょうど良い仕事をしますし、より高速だと思います。

いったんドキュメントを lxml ツリーにパースした後は .xpath() メソッドを使って要素を検索します。

try:
    # Python 2
    from urllib2 import urlopen
except ImportError:
    from urllib.request import urlopen
from lxml import etree

url =  "http://www.example.com/servlet/av/ResultTemplate=AVResult.html"
response = urlopen(url)
htmlparser = etree.HTMLParser()
tree = etree.parse(response, htmlparser)
tree.xpath(xpathselector)

また 専用の lxml.html() モジュール を追加したものです。

上の例で、私は response オブジェクトを直接 lxml というのは、パーサーがストリームから直接読み込む方が、 応答を最初に大きな文字列に読み込むより効率的だからです。同じことを requests ライブラリと同じことをするには stream=True を渡して response.raw オブジェクトを渡す。 トランスポートの透過的な伸張を有効にした後 :

import lxml.html
import requests

url =  "http://www.example.com/servlet/av/ResultTemplate=AVResult.html"
response = requests.get(url, stream=True)
response.raw.decode_content = True
tree = lxml.html.parse(response.raw)

あなたが興味を持つ可能性があるのは CSS セレクタのサポート で、これは CSSSelector クラスは CSS ステートメントを XPath 式に変換し、検索を td.empformbody の検索をより簡単にします。

from lxml.cssselect import CSSSelector

td_empformbody = CSSSelector('td.empformbody')
for elem in td_empformbody(tree):
    # Do something with these table cells.

一周回って: BeautifulSoupそのもの は行います。 は非常に完全な CSS セレクタのサポート :

for cell in soup.select('table#foobar td.empformbody'):
    # Do something with these table cells.