শ্রেণি দ্বারা উপাদানগুলি কীভাবে সন্ধান করা যায়


386

বিউটিউলসাপ ব্যবহার করে "ক্লাস" অ্যাট্রিবিউট দিয়ে এইচটিএমএল উপাদানগুলি পার্স করতে আমার সমস্যা হচ্ছে। কোডটি এরকম দেখাচ্ছে

soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs: 
    if (div["class"] == "stylelistrow"):
        print div

স্ক্রিপ্ট শেষ হওয়ার পরে "একই" লাইনে আমি একটি ত্রুটি পেয়েছি।

File "./beautifulcoding.py", line 130, in getlanguage
  if (div["class"] == "stylelistrow"):
File "/usr/local/lib/python2.6/dist-packages/BeautifulSoup.py", line 599, in __getitem__
   return self._getAttrMap()[key]
KeyError: 'class'

আমি কীভাবে এই ত্রুটি থেকে মুক্তি পাব?

উত্তর:


646

আপনি কেবল বিএস 3 ব্যবহার করে প্রদত্ত শ্রেণীর সাথে সেই ডিভগুলি সন্ধান করতে আপনার অনুসন্ধানকে পরিমার্জন করতে পারেন:

mydivs = soup.findAll("div", {"class": "stylelistrow"})

@ ক্লাউস- আমি যদি এর পরিবর্তে সন্ধানের সমস্তটি ব্যবহার করতে চাই তবে কী হবে?

1
এর জন্য ধন্যবাদ. এটি কেবল ক্লাসের জন্য নয়, যে কোনও কিছুর জন্য।
প্রেজেন্ট করুন

41
এটি কেবল সঠিক ম্যাচের জন্য কাজ করে। <.. class="stylelistrow">ম্যাচ কিন্তু না <.. class="stylelistrow button">
ওয়ার্নাইট

4
@pyCthon @ jmunsch এর উত্তর দেখুন, বিএস এখন সমর্থন করে class_যা সঠিকভাবে কাজ করে।
ওয়ার্নাইট

25
সুন্দরীসুফ 4 হিসাবে, সন্ধানের সমস্তটি এখন সন্ধান_ সবই
নিওকোস

273

ডকুমেন্টেশন থেকে:

বিউটিফুল স্যুপ ৪.১.২ হিসাবে, আপনি কীওয়ার্ড আর্গুমেন্টটি ব্যবহার করে সিএসএস শ্রেণিতে অনুসন্ধান করতে পারেন class_ :

soup.find_all("a", class_="sister")

এই ক্ষেত্রে যা হতে পারে:

soup.find_all("div", class_="stylelistrow")

এটি এর জন্যও কাজ করবে:

soup.find_all("div", class_="stylelistrowone stylelistrowtwo")

5
আপনি তালিকাও ব্যবহার করতে পারেন: soup.find_all("a", ["stylelistrowone", "stylelistrow"])আপনার কাছে অনেক ক্লাস না থাকলে এটি নিরাপদ।
নুনো আন্দ্রে

4
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত, এটি বিকল্পগুলির চেয়ে আরও সঠিক এবং সংক্ষিপ্ত উভয়ই।
goncalopp

1
@ BeautifulSoup 3 NunoAndré এর উত্তর সাপ্লিমেন্ট: soup.findAll("a", {'class':['stylelistrowone', 'stylelistrow']})
ব্র্যাড

55

আপডেট: ২০১ beautiful বিউটিসুপের সর্বশেষতম সংস্করণে, পদ্ধতি 'ফাইন্ডআল'-এর নাম পরিবর্তন করে' ফাইন্ড_ল 'করা হয়েছে। অফিসিয়াল ডকুমেন্টেশনের লিঙ্ক

পদ্ধতির নামের তালিকা পরিবর্তন করা হয়েছে

সুতরাং উত্তর হবে

soup.find_all("html_element", class_="your_class_name")

18

বিউটিউসলসপ 3 এর জন্য নির্দিষ্ট:

soup.findAll('div',
             {'class': lambda x: x 
                       and 'stylelistrow' in x.split()
             }
            )

এই সমস্ত খুঁজে পাবেন:

<div class="stylelistrow">
<div class="stylelistrow button">
<div class="button stylelistrow">

কেন পুনরায় অনুসন্ধান করবেন না ('। * স্টাইললিস্টো। *', এক্স)?
rjurney

কারণ তখন স্টাইললিস্ট 2 মিলবে। ভাল মন্তব্য "পুনরায় পরিবর্তে স্ট্রিং.ফাইন্ড () ব্যবহার করবেন না কেন?"
ফ্লিপএমসিএফ

2
lambda x: 'stylelistrow' in x.split()সহজ এবং সুন্দর
ফেফেরি

এবং আমি রেজিওসগুলিকে ঘৃণা করি। ধন্যবাদ! (উত্তর আপডেট করা) | কারও পরীক্ষার জন্য 'এক্স এবং'
রাখছেন

16

সোজা এগিয়ে যাওয়ার উপায় হ'ল:

soup = BeautifulSoup(sdata)
for each_div in soup.findAll('div',{'class':'stylelist'}):
    print each_div

নিশ্চিত করুন যে আপনি ফাইন্ডএলের সমস্ত আবরণ গ্রহণ করেছেন , এটি ফোল্ডাল নয়


4
এটি কেবল সঠিক ম্যাচের জন্য কাজ করে। <.. class="stylelistrow">ম্যাচ কিন্তু না <.. class="stylelistrow button">
ওয়ার্নাইট

11

শ্রেণি দ্বারা উপাদানগুলি কীভাবে সন্ধান করা যায়

বিউটিউসসুপ ব্যবহার করে "শ্রেণি" অ্যাট্রিবিউট দিয়ে এইচটিএমএল উপাদানগুলি পার্স করতে আমার সমস্যা হচ্ছে।

আপনি সহজেই একটি শ্রেণি দ্বারা সন্ধান করতে পারেন, তবে আপনি যদি দুটি শ্রেণীর ছেদ দ্বারা সন্ধান করতে চান তবে এটি কিছুটা বেশি কঠিন,

ডকুমেন্টেশন থেকে (জোর দেওয়া):

আপনি যদি দুটি বা ততোধিক CSS ক্লাসের সাথে মেলে এমন ট্যাগগুলির সন্ধান করতে চান তবে আপনার একটি সিএসএস নির্বাচক ব্যবহার করা উচিত:

css_soup.select("p.strikeout.body")
# [<p class="body strikeout"></p>]

পরিষ্কার হওয়ার জন্য, এটি কেবলমাত্র স্ট্রিংআউট এবং দেহ শ্রেণীর উভয়ই প ট্যাগগুলি নির্বাচন করে।

ক্লাসের একটি সেট (ছেদ নয়, তবে ইউনিয়ন) এর যে কোনও ছেদটির সন্ধানের জন্য , আপনি class_কীওয়ার্ড আর্গুমেন্টের (4.1.2 হিসাবে) একটি তালিকা দিতে পারেন :

soup = BeautifulSoup(sdata)
class_list = ["stylelistrow"] # can add any other classes to this list.
# will find any divs with any names in class_list:
mydivs = soup.find_all('div', class_=class_list) 

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


11

সিএসএস নির্বাচক

একক শ্রেণির প্রথম ম্যাচ

soup.select_one('.stylelistrow')

ম্যাচের তালিকা

soup.select('.stylelistrow')

যৌগিক শ্রেণি (যেমন এবং অন্য শ্রেণি)

soup.select_one('.stylelistrow.otherclassname')
soup.select('.stylelistrow.otherclassname')

যৌগিক শ্রেণীর নামের শূন্যস্থান যেমন class = stylelistrow otherclassname "" দিয়ে প্রতিস্থাপন করা হয়। আপনি ক্লাস যুক্ত করা চালিয়ে যেতে পারেন।

ক্লাসগুলির তালিকা (বা - যা উপস্থিত তা মিলবে

soup.select_one('.stylelistrow, .otherclassname')
soup.select('.stylelistrow, .otherclassname')

bs4 4.7.1 +

নির্দিষ্ট স্ট্রেস যার innerTextস্ট্রিং রয়েছে

soup.select_one('.stylelistrow:contains("some string")')
soup.select('.stylelistrow:contains("some string")')

নির্দিষ্ট ক্লাসে একটি নির্দিষ্ট সন্তানের উপাদান রয়েছে যেমন aট্যাগ

soup.select_one('.stylelistrow:has(a)')
soup.select('.stylelistrow:has(a)')

5

বিউটিফুলসপ 4+ হিসাবে,

আপনার যদি একক শ্রেণীর নাম থাকে তবে আপনি ক্লাসের নামটি কেবল প্যারামিটার হিসাবে পাস করতে পারেন:

mydivs = soup.find_all('div', 'class_name')

বা আপনার যদি একাধিক শ্রেণীর নাম থাকে তবে কেবলমাত্র পরামিতি হিসাবে শ্রেণীর নামের তালিকাটি পাস করুন:

mydivs = soup.find_all('div', ['class1', 'class2'])

3

ডিভের প্রথম শ্রেণীর বৈশিষ্ট্য আছে কিনা তা যাচাই করার চেষ্টা করুন:

soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs:
    if "class" in div:
        if (div["class"]=="stylelistrow"):
            print div

1
যে কাজ করে না। আমার ধারণা আপনার পদ্ধতির সঠিক ছিল, তবে চতুর্থ লাইনটি যেমন ইচ্ছা তেমন কাজ করে না।
নিও

1
আহ আমি ভাবছিলাম ডিভ অভিধানের মতো কাজ করেছে, আমি বিউটিফুল স্যুপের সাথে সত্যিই পরিচিত নই সুতরাং এটি কেবল অনুমান ছিল।
মেঘ

3

এটি আমার জন্য ক্লাস অ্যাট্রিবিউট অ্যাক্সেস করার জন্য কাজ করে (ডুমেন্টেশন যা বলে তার বিপরীতে বিউটিউসসপ 4)। কী-অরোর একটি তালিকা আসে না এমন একটি তালিকা আসে।

for hit in soup.findAll(name='span'):
    print hit.contents[1]['class']



1

বিকল্পভাবে আমরা lxML ব্যবহার করতে পারি, এটি এক্সপথ সমর্থন করে এবং খুব দ্রুত!

from lxml import html, etree 

attr = html.fromstring(html_text)#passing the raw html
handles = attr.xpath('//div[@class="stylelistrow"]')#xpath exresssion to find that specific class

for each in handles:
    print(etree.tostring(each))#printing the html as string

0

এই কাজ করা উচিত:

soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs: 
    if (div.find(class_ == "stylelistrow"):
        print div

0

অন্যান্য উত্তরগুলি আমার পক্ষে কার্যকর হয়নি।

অন্যান্য উত্তরে findAllস্যুপ বস্তুটিতে নিজেই এটি ব্যবহৃত হচ্ছে, তবে কাজটি করার পরে আমি যে বস্তুটি পেয়েছি তার থেকে পাওয়া নির্দিষ্ট উপাদানটির অভ্যন্তরে বস্তুর উপর শ্রেণীর নাম অনুসারে অনুসন্ধান করার একটি উপায় আমার প্রয়োজন ছিল findAll

শ্রেণীর নাম অনুসারে বস্তু পেতে আপনি যদি নেস্টেড এইচটিএমএল উপাদানগুলির মধ্যে কোনও অনুসন্ধান করার চেষ্টা করছেন তবে নীচে চেষ্টা করুন -

# parse html
page_soup = soup(web_page.read(), "html.parser")

# filter out items matching class name
all_songs = page_soup.findAll("li", "song_item")

# traverse through all_songs
for song in all_songs:

    # get text out of span element matching class 'song_name'
    # doing a 'find' by class name within a specific song element taken out of 'all_songs' collection
    song.find("span", "song_name").text

লক্ষ্য করার বিষয়গুলি:

  1. আমি অনুসন্ধানটি 'শ্রেণি' বৈশিষ্ট্যটিতে স্পষ্টভাবে সংজ্ঞায়িত করছি না findAll("li", {"class": "song_item"}), যেহেতু এটিই কেবলমাত্র আমি যা অনুসন্ধান করছি সেগুলি এবং এটি ডিফল্টরূপে শ্রেণীর বৈশিষ্ট্যের জন্য অনুসন্ধান করবে যদি আপনি নির্দিষ্টভাবে কোন বৈশিষ্ট্যটি অনুসন্ধান করতে চান তা না বললে।

  2. যখন আপনি একটি findAllবা করেন find, ফলস্বরূপ অবজেক্টটি শ্রেণীর bs4.element.ResultSetযা একটি সাবক্লাস list। সমস্ত অনুসন্ধান বা অনুসন্ধান করার জন্য আপনি যে কোনও ResultSetনেস্টেড উপাদানগুলির (যতক্ষণ তারা প্রকারের মধ্যে থাকে ResultSet) এর অভ্যন্তরের সমস্ত পদ্ধতি ব্যবহার করতে পারেন ।

  3. আমার BS4 সংস্করণ - 4.9.1, পাইথন সংস্করণ - 3.8.1


0

নিম্নলিখিত কাজ করা উচিত

soup.find('span', attrs={'class':'totalcount'})

আপনার শ্রেণীর নাম এবং 'স্প্যান' ট্যাগটি আপনার শ্রেণীর নামের সাথে প্রতিস্থাপন করুন। এছাড়াও, যদি আপনার শ্রেণিতে স্থান সহ একাধিক নাম থাকে, কেবল একটি চয়ন করুন এবং ব্যবহার করুন।

পিএস এটি প্রদত্ত মানদণ্ড সহ প্রথম উপাদানটি সন্ধান করে। আপনি যদি সমস্ত উপাদান সন্ধান করতে চান তবে 'ফাইন্ড_ল'-এর সাথে' অনুসন্ধান 'প্রতিস্থাপন করুন।

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