programing

XPath를 BeautifulSoup과 함께 사용할 수 있습니까?

lovejava 2023. 7. 18. 21:22

XPath를 BeautifulSoup과 함께 사용할 수 있습니까?

저는 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를 사용할 수 있습니까?가능하다면 샘플 코드를 제공해주시기 바랍니다.

아니요, BeautifulSoup 자체는 XPath 표현식을 지원하지 않습니다.

대체 라이브러리인 lxml은 XPath 1.0을 지원합니다.BeautifulSoup 호환 모드를 사용하여 Soup처럼 깨진 HTML을 분석합니다.그러나 기본 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)

추가 기능이 있는 전용 모듈도 있습니다.

위의 예에서 나는 다음을 통과했습니다.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 Selector 지원입니다.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.

Beautiful Soup 내에서 XPath 지원이 없음을 확인할 수 있습니다.

다른 사람들이 말했듯이 BeautifulSoup은 xpath를 지원하지 않습니다.아마도 셀레늄을 사용하는 것을 포함하여 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)

저는 이것을 참고 자료로 사용했습니다.

BeautifulSoup에는 현재 요소에서 지시된 children에서 findNext라는 이름의 함수가 있으므로 다음과 같습니다.

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

위의 코드는 다음과 같은 xpath를 모방할 수 있습니다.

div[class=class_value]/div[id=id_value]
from lxml import etree
from bs4 import BeautifulSoup
soup = BeautifulSoup(open('path of your localfile.html'),'html.parser')
dom = etree.HTML(str(soup))
print dom.xpath('//*[@id="BGINP01_S1"]/section/div/font/text()')

위에서는 Soup 개체와 lxml의 조합을 사용했으며 xpath를 사용하여 값을 추출할 수 있습니다.

lxml을 모두 단순하게 사용하는 경우:

tree = lxml.html.fromstring(html)
i_need_element = tree.xpath('//a[@class="shared-components"]/@href')

그러나 BeautifulSoup BS4를 사용할 때는 모든 것이 간단합니다.

  • 먼저 "//" 및 "@"를 제거합니다.
  • 두 번째 - "=" 앞에 별 추가

이 마법을 사용해 보십시오.

soup = BeautifulSoup(html, "lxml")
i_need_element = soup.select ('a[class*="shared-components"]')

보시다시피, 이것은 하위 태그를 지원하지 않으므로 "/@href" 부분을 제거합니다.

그들의 서류를 찾아보니 XPath 옵션은 없는 것 같습니다.

또한 SO에 대한 유사한 질문에 대해 여기에서 수 있듯이 OP는 XPath에서 BeautifulSoup로 번역을 요청하고 있으므로 결론은 - 아니요, 사용 가능한 XPath 구문 분석이 없습니다.

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'))

이것은 꽤 오래된 스레드이지만, 현재 해결책이 있습니다. 당시 BeautifulSoup에는 없었을 수도 있습니다.

여기 제가 한 일의 예가 있습니다.저는 "requests" 모듈을 사용하여 RSS 피드를 읽고 "rss_text"라는 변수로 텍스트 내용을 가져옵니다.그런 다음 BeautifulSoup을 통해 실행하고 xpath /rss/channel/title을 검색하여 내용을 검색합니다.모든 영광(와일드카드, 다중 경로 등)에서 XPath는 아니지만, 찾고자 하는 기본 경로만 있다면 이 기능이 작동합니다.

from bs4 import BeautifulSoup
rss_obj = BeautifulSoup(rss_text, 'xml')
cls.title = rss_obj.rss.channel.title.get_text()

사용하다soup.find(class_='myclass')

언급URL : https://stackoverflow.com/questions/11465555/can-we-use-xpath-with-beautifulsoup