139

私はBeautifulSoupを使用してURLをスクレイプし、次のコードを使用して、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を使用することは可能ですか?可能であれば、サンプルコードを教えてください。

4

10 に答える 10

206

いいえ、BeautifulSoup 自体は XPath 式をサポートしていません。

代替ライブラリlxmlは、XPath 1.0 をサポートしています。壊れた HTML をスープのように解析しようとする BeautifulSoup 互換モードがありますただし、デフォルトの 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ライブラリで同じことを行うには、transparent transport decompression を有効にした後、オブジェクトを設定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.
于 2012-07-13T07:31:41.127 に答える
171

BeautifulSoup内にXPathサポートがないことを確認できます。

于 2012-07-13T11:44:45.663 に答える
55

他の人が言ったように、BeautifulSoup は xpath をサポートしていません。Selenium を使用するなど、xpath から何かを取得する方法はおそらくいくつかあります。ただし、Python 2 または 3 で機能するソリューションを次に示します。

from lxml import html
import requests

page = requests.get('http://econpy.pythonanywhere.com/ex/001.html')
tree = html.fromstring(page.content)
#This will create a list of buyers:
buyers = tree.xpath('//div[@title="buyer-name"]/text()')
#This will create a list of prices
prices = tree.xpath('//span[@class="item-price"]/text()')

print('Buyers: ', buyers)
print('Prices: ', prices)

これを参考にしました。

于 2017-01-06T21:38:07.587 に答える
19

BeautifulSoup には、 childernを指示する現在の要素からのfindNextという名前の関数があります。

father.findNext('div',{'class':'class_value'}).findNext('div',{'id':'id_value'}).findAll('a') 

上記のコードは、次の xpath を模倣できます。

div[class=class_value]/div[id=id_value]
于 2014-07-09T13:11:19.327 に答える
3

ドキュメントを検索したところ、XPath オプションがないようです。

また、ここでSOに関する同様の質問を見ることができるように、OPはXPathからBeautifulSoupへの翻訳を求めているので、私の結論は-いいえ、利用可能なXPath解析はありません.

于 2012-07-13T07:30:25.333 に答える
1

たぶん、XPathなしで次を試すことができます

from simplified_scrapy.simplified_doc import SimplifiedDoc 
html = '''
<html>
<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is for use in illustrative examples in documents. You may use this
    domain in literature without prior coordination or asking for permission.</p>
    <p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
'''
# What XPath can do, so can it
doc = SimplifiedDoc(html)
# The result is the same as doc.getElementByTag('body').getElementByTag('div').getElementByTag('h1').text
print (doc.body.div.h1.text)
print (doc.div.h1.text)
print (doc.h1.text) # Shorter paths will be faster
print (doc.div.getChildren())
print (doc.div.getChildren('p'))
于 2019-12-06T08:44:12.967 に答える