2012-07-13 12 views
66

मैं BeautifulSoup उपयोग कर रहा हूँ एक यूआरएल स्क्रैप करने का और मैं निम्नलिखित कोड थाक्या हम सुंदर सूप के साथ xpath का उपयोग कर सकते हैं?

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 उपयोग करना चाहते हैं। क्या सुंदरपॉप के साथ xpath का उपयोग करना संभव है? यदि संभव हो, तो क्या कोई मुझे एक उदाहरण कोड प्रदान कर सकता है ताकि यह और अधिक सहायक हो?

उत्तर

108

नहीं, BeautifulSoup, अपने आप में, xPath अभिव्यक्ति का समर्थन नहीं करता।

एक वैकल्पिक लाइब्रेरी, lxml, समर्थन XPath 1.0 है। इसमें BeautifulSoup compatible mode है जहां यह सूप करता है जिस तरह से एचटीएमएल टूटी हुई कोशिश करेगा। हालांकि, default lxml HTML parser टूटा एचटीएमएल पार्स करने का उतना ही अच्छा एक काम करता है, और मेरा मानना ​​है कि तेजी से होता है।

एक बार जब आप अपने दस्तावेज़ को lxml पेड़ में पार्स कर लेते हैं, तो आप तत्वों की खोज के लिए .xpath() विधि का उपयोग कर सकते हैं।

import urllib2 
from lxml import etree 

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

आपके लिए संभावित रुचि CSS Selector support है;

from lxml.cssselect import CSSSelector 

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

आ रहा है चक्र पूरा: CSSSelector वर्ग आसान xPath अभिव्यक्ति में सीएसएस बयान तब्दील हो, इतना td.empformbody के लिए अपनी खोज बनाने BeautifulSoup ही करता है सुंदर सभ्य CSS selector support:

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

बहुत बहुत धन्यवाद पीटर, मुझे आपके कोड से दो सूचनाएं मिलीं, 1। एक स्पष्टीकरण कि हम बीएस 2 के साथ xpath का उपयोग नहीं कर सकते हैं। Lxml का उपयोग करने के तरीके पर एक अच्छा उदाहरण। क्या हम इसे एक विशेष दस्तावेज़ीकरण पर देख सकते हैं कि "हम लिखित रूप में बीएस का उपयोग करके xpath लागू नहीं कर सकते हैं", क्योंकि हमें उन लोगों को कुछ सबूत दिखाना चाहिए जो स्पष्टीकरण के लिए सही पूछते हैं? –

+0

वैसे भी धन्यवाद आपके लिए preciuos मदद –

+6

नकारात्मक साबित करना मुश्किल है; [सुंदर सूप 4 प्रलेखन] (http://www.crummy.com/software/BeautifulSoup/bs4/doc/) में एक खोज फ़ंक्शन है और 'xpath' के लिए कोई हिट नहीं है। –

1

मैं उनके docs के माध्यम से खोज की है और ऐसा लगता है वहाँ नहीं है xpath विकल्प। इसके अलावा, जैसा कि आप अतः, ओपी xpath से BeautifulSoup करने के लिए एक अनुवाद के लिए पूछ रहा है, तो मेरे निष्कर्ष होगा पर एक समान प्रश्न पर here देख सकते हैं - नहीं, वहाँ कोई xpath उपलब्ध पार्स करने है।

+0

[ 'scrapy'] (http://scrapy.org/) मैं scrapy जो tags.Its अंदर डेटा प्राप्त करने का xpath का उपयोग करता है के लिए इस्तेमाल किया अब तक बुद्धि बी एस – inspectorG4dget

+0

हाँ वास्तव में काम कर lxml प्राप्त करने के लिए एक और विकल्प बहुत डेटा लाने के लिए आसान और आसान है, लेकिन मुझे सुंदरसप के साथ ऐसा करने की आवश्यकता है ताकि इसमें आगे की तलाश हो। –

77

मैं पुष्टि कर सकता कि सुंदर सूप के भीतर कोई XPath समर्थन नहीं है।

+46

नोट: लियोनार्ड रिचर्डसन सुंदर सूप के लेखक हैं, क्योंकि आप देखेंगे कि क्या आप उनके उपयोगकर्ता प्रोफ़ाइल पर क्लिक करते हैं। – senshin

+13

सुंदर सूप – DarthOpto

+0

के भीतर XPATH का उपयोग करने में सक्षम होना बहुत अच्छा होगा तो विकल्प क्या है? –

9

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] 
16

Martijn के कोड नहीं रह गया है ठीक से काम करता है (यह 4 + अब ... द्वारा वर्ष वर्ष), कंसोल के लिए etree.parse() लाइन प्रिंट और tree चर के मूल्य निर्दिष्ट नहीं है। this संदर्भित, मैं यह पता लगाने की यह अनुरोध और lxml का उपयोग कर काम करता है में सक्षम था:

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 
0

यह एक बहुत पुराने धागा है, लेकिन एक काम के आसपास समाधान अब वहाँ है, जो उस समय BeautifulSoup में किया गया है नहीं हो सकता है ।

यहां मैंने जो किया है उसका एक उदाहरण है। मैं एक आरएसएस फ़ीड पढ़ने के लिए "अनुरोध" मॉड्यूल का उपयोग करता हूं और इसकी टेक्स्ट सामग्री को "rss_text" नामक चर में प्राप्त करता हूं। इसी के साथ, मैं इसे BeautifulSoup के माध्यम से चलाने के लिए, xpath/आरएसएस/चैनल/शीर्षक के लिए खोज, और उसकी सामग्री को पुनः प्राप्त। यह बिल्कुल अपनी महिमा (वाइल्डकार्ड, एकाधिक पथ इत्यादि) में XPath नहीं है, लेकिन यदि आपके पास केवल एक मूल पथ है जिसे आप ढूंढना चाहते हैं, तो यह काम करता है।

from bs4 import BeautifulSoup 
rss_obj = BeautifulSoup(rss_text, 'xml') 
cls.title = rss_obj.rss.channel.title.get_text() 
संबंधित मुद्दे