আমরা কি বিউটিফুলসপ দিয়ে এক্সপথ ব্যবহার করতে পারি?


105

আমি ইউআরএল স্ক্র্যাপ করতে বিউটিফুলসুপ ব্যবহার করছি এবং আমার নিম্নলিখিত কোডটি ছিল

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তাদের সম্পর্কিত ট্যাগ এবং তথ্য পেতে ব্যবহার করতে পারি, তবে আমি এক্সপথ ব্যবহার করতে চাই। বিউটিফুলসপ দিয়ে এক্সপথ ব্যবহার করা কি সম্ভব? যদি সম্ভব হয় তবে কেউ দয়া করে আমাকে একটি উদাহরণ কোড সরবরাহ করতে পারেন যাতে এটি আরও সহায়ক হয়?

উত্তর:


168

নাপ, বিউটিফুলসুপ নিজে থেকে এক্সপাথ এক্সপ্রেশন সমর্থন করে না।

একটি বিকল্প গ্রন্থাগার, lxml , না সমর্থন জন্য XPath 1.0। এটির একটি বিউটিফুলসপ সামঞ্জস্যপূর্ণ মোড রয়েছে যেখানে এটি স্যুপের মতো ভাঙ্গা এইচটিএমএলকে চেষ্টা এবং বিশ্লেষণ করবে। যাইহোক, ডিফল্ট lxML এইচটিএমএল পার্সার ভাঙা এইচটিএমএল পার্স করার ঠিক ততটাই ভাল কাজ করে এবং আমি বিশ্বাস করি এটি দ্রুত faster

একবার আপনি আপনার ডকুমেন্টকে একটি এলএক্সএমএল গাছে পার্স করার পরে, .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)

আপনার পক্ষে সম্ভাব্য আগ্রহের বিষয় হল সিএসএস নির্বাচনকারী সমর্থন ; CSSSelectorবর্গ জন্য 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.

2
অনেক ধন্যবাদ পিটারস, আমি আপনার কোড থেকে দুটি তথ্য পেয়েছি, 1। একটি স্পষ্টতা যা আমরা BS 2. এর সাথে এক্সপথ ব্যবহার করতে পারি না lxML কীভাবে ব্যবহার করবেন তার একটি দুর্দান্ত উদাহরণ। আমরা কী এটি একটি নির্দিষ্ট নথিতে দেখতে পাচ্ছি যে "লিখিত আকারে বিএস ব্যবহার করে আমরা এক্সপথ প্রয়োগ করতে পারি না", কারণ আমরা যারা স্পষ্টতার জন্য সঠিকভাবে জিজ্ঞাসা করি তাদের কাউকে কিছু প্রমাণ দেখাতে হবে?
শিব কৃষ্ণ বাওয়ান্ডলা

8
নেতিবাচক প্রমাণ করা শক্ত; BeautifulSoup 4 ডকুমেন্টেশন একটি অনুসন্ধান ফাংশন এবং সেখানে 'xPath' এর জন্য কোনো হিট হয়।
মার্টিজন পিটারস

122

আমি নিশ্চিত করতে পারি যে বিউটিফুল স্যুপের মধ্যে কোনও এক্সপথ সমর্থন নেই।


76
দ্রষ্টব্য: লিওনার্ড রিচার্ডসন হলেন বিউটিফুল স্যুপের লেখক, আপনি দেখতে পাবেন যে আপনি যদি তার ব্যবহারকারীর প্রোফাইলে ক্লিক করেন কিনা।
সেনশিন

23
বিউটিফুলসপ
ডারথঅপ্টো

4
তাহলে বিকল্প কী?
স্ট্যাটিক_আরটিটি

40

অন্যরা যেমন বলেছে, বিউটিফুলসপের এক্সপথ সমর্থন নেই। এক্সপ্যাথ থেকে সেলেনিয়াম ব্যবহার সহ কিছু পাওয়ার জন্য সম্ভবত বেশ কয়েকটি উপায় রয়েছে। যাইহোক, এখানে একটি সমাধান যা পাইথন 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)

আমি ব্যবহৃত এই একটি রেফারেন্স হিসাবে।


একটি সতর্কতা: আমি লক্ষ্য করেছি যে শিকড়ের বাইরে কিছু রয়েছে (যেমন বাইরের <html> ট্যাগগুলির বাইরে \ n), তবে মূল দ্বারা এক্সপথগুলি উল্লেখ করা কার্যকর হবে না, আপনাকে আপেক্ষিক এক্সপথ ব্যবহার করতে হবে। lxML.de/xpathxslt.html
শব্দসুবিধা

মার্টিজনের কোডটি আর সঠিকভাবে কাজ করে না (এটি এখন 4+ বছরের বেশি পুরানো ...), etree.parse () লাইনটি কনসোলে প্রিন্ট করে এবং ট্রি ভেরিয়েবলের মান নির্ধারণ করে না। এটা বেশ দাবি। আমি অবশ্যই এটি পুনরুত্পাদন করতে পারি না এবং এটি কোনও অর্থবোধ করে না । আপনি কি নিশ্চিত যে আপনি আমার কোডটি পরীক্ষা করার জন্য পাইথন 2 ব্যবহার করছেন, বা urllib2পাইথন 3 এ লাইব্রেরিটির ব্যবহারটি অনুবাদ করেছেন urllib.request?
মার্টিজন পিটারস

হ্যাঁ, এটি লেখার সময় আমি পাইথন 3 ব্যবহার করেছি এবং এটি প্রত্যাশার মতো কার্যকর হয়নি। শুধু পরীক্ষিত এবং আপনার নিজের Python2 সাথে কাজ করে, কিন্তু Python3 অনেক পছন্দ করা হয় যেমন 2 সূর্যাস্ত হচ্ছে (আর আনুষ্ঠানিকভাবে সমর্থিত) মধ্যে 2020. হয়
wordsforthewise

একেবারে একমত, তবে এখানে প্রশ্নটি পাইথন 2 ব্যবহার করে
মার্টিজান পিটারস

17

বিউটিফুলসুপের বর্তমান উপাদান পরিচালিত চাইল্ডার্ন থেকে ফাইন্ডেক্সট নামে একটি ফাংশন রয়েছে , তাই:

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

উপরের কোডটি নিম্নলিখিত এক্সপথটিকে অনুকরণ করতে পারে:

div[class=class_value]/div[id=id_value]

1

আমি তাদের দস্তাবেজগুলি অনুসন্ধান করেছি এবং দেখে মনে হচ্ছে এটির কোনও এক্সপথ বিকল্প নেই। এছাড়াও, আপনি এখানে এসও সম্পর্কিত অনুরূপ প্রশ্নে দেখতে পারেন , ওপি এক্সপথ থেকে বিউটিফুলসুপে অনুবাদ চাইছে, তাই আমার উপসংহারটি হবে - না, কোনও এক্সপথ পার্সিং উপলব্ধ নেই।


হ্যাঁ আসলে এখনও অবধি আমি স্কেরাপি ব্যবহার করেছি যা ট্যাগগুলির অভ্যন্তরে ডেটা আনার জন্য এক্সপথ ব্যবহার করে I এটি খুব সহজ এবং ডেটা আনার পক্ষে সহজ, তবে আমি এটির অপেক্ষায় সুন্দরী স্যুপের সাথে একই কাজ করার দরকার পড়েছিলাম।
শিব কৃষ্ণ বাওয়ান্ডলা

1

আপনি যখন সমস্ত সাধারণ ব্যবহার করতে পারেন:

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

তবে যখন বিউটিফুলসপ বিএস 4 ব্যবহার করুন তখন খুব সহজ:

  • প্রথমে "//" এবং "@" সরান
  • দ্বিতীয় - "=" এর আগে তারা যুক্ত করুন

এই যাদু চেষ্টা করুন:

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

যেমনটি আপনি দেখুন, এটি সাব-ট্যাগ সমর্থন করে না, তাই আমি "/ @ href" অংশটি সরিয়েছি


select()সিএসএস নির্বাচকদের জন্য, এটি মোটেই এক্সপথ নয়। যেমন আপনি দেখতে পাচ্ছেন, এটি সাব-ট্যাগ সমর্থন করে না যদিও আমি নিশ্চিত নই যে সে সময় এটি সত্য ছিল কিনা, এটি অবশ্যই এখন নেই।
এএমসি

1

হতে পারে আপনি এক্সপথ ছাড়াই নিম্নলিখিতগুলি চেষ্টা করে দেখতে পারেন

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

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

উপরে lxML এর সাথে স্যুপ অবজেক্টের সংমিশ্রণ ব্যবহৃত হয়েছে এবং এক্সপ্যাথ ব্যবহার করে কেউ মান বের করতে পারে


0

এটি বেশ পুরানো থ্রেড, তবে এখন একটি কাজের আশেপাশের সমাধান রয়েছে, যা সম্ভবত বিউটিউলসাপে ছিল না।

আমি যা করেছি তার একটি উদাহরণ এখানে। আমি আরএসএস ফিড পড়ার জন্য "অনুরোধগুলি" মডিউলটি ব্যবহার করি এবং "আরএসএস_টেক্সট" নামক একটি ভেরিয়েবলে এর পাঠ্য সামগ্রী পেতে পারি। এটির সাহায্যে, আমি এটি বিউটিফুলসুপের মাধ্যমে চালাচ্ছি, এক্সপাথ / আরএসএস / চ্যানেল / শিরোনাম অনুসন্ধান করব এবং এর সামগ্রীগুলি পুনরুদ্ধার করব। এটি এর সমস্ত গৌরবতে (ওয়াইল্ডকার্ডস, একাধিক পাথ, ইত্যাদি) ঠিক এক্সপথ নয়, তবে আপনার যদি কেবল একটি প্রাথমিক পথ খুঁজে পেতে চান তবে এটি কার্যকর।

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

আমি বিশ্বাস করি এটি কেবলমাত্র শিশু উপাদানগুলি খুঁজে পায়। এক্সপাথ আরেকটি জিনিস?
রাফায়েম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.