উত্তর:
বিউটিফুলসুপে স্যুপস্প্রেনার ক্লাসটি ব্যবহার করে একটি ছোট স্নিপেট এখানে দেওয়া হয়েছে:
import httplib2
from bs4 import BeautifulSoup, SoupStrainer
http = httplib2.Http()
status, response = http.request('http://www.nytimes.com')
for link in BeautifulSoup(response, parse_only=SoupStrainer('a')):
if link.has_attr('href'):
print(link['href'])
বিউটিফুলসুপ ডকুমেন্টেশনটি আসলে বেশ ভাল এবং এতে বেশ কয়েকটি সাধারণ পরিস্থিতি রয়েছে:
https://www.crummy.com/software/BeautifulSoup/bs4/doc/
সম্পাদনা করুন: নোট করুন যে আমি স্যুপস্প্রেনার ক্লাসটি ব্যবহার করেছি কারণ এটি কিছুটা দক্ষ (স্মৃতিশক্তি এবং গতিযুক্ত), যদি আপনি জানেন যে আপনি কী পূর্বে পার্স করছেন।
/usr/local/lib/python2.7/site-packages/bs4/__init__.py:128: UserWarning: The "parseOnlyThese" argument to the BeautifulSoup constructor has been renamed to "parse_only."
has_attr
। পরিবর্তে আমি দেখি এখানে কিছু আছে has_key
এবং এটি কাজ করে।
সম্পূর্ণতার জন্য, বিউটিফুলসপ 4 সংস্করণ, সার্ভার দ্বারা সরবরাহিত এনকোডিংটি ব্যবহার করে:
from bs4 import BeautifulSoup
import urllib.request
parser = 'html.parser' # or 'lxml' (preferred) or 'html5lib', if installed
resp = urllib.request.urlopen("http://www.gpsbasecamp.com/national-parks")
soup = BeautifulSoup(resp, parser, from_encoding=resp.info().get_param('charset'))
for link in soup.find_all('a', href=True):
print(link['href'])
বা পাইথন 2 সংস্করণ:
from bs4 import BeautifulSoup
import urllib2
parser = 'html.parser' # or 'lxml' (preferred) or 'html5lib', if installed
resp = urllib2.urlopen("http://www.gpsbasecamp.com/national-parks")
soup = BeautifulSoup(resp, parser, from_encoding=resp.info().getparam('charset'))
for link in soup.find_all('a', href=True):
print link['href']
এবং requests
গ্রন্থাগারটি ব্যবহার করে এমন একটি সংস্করণ যা লিখিতভাবে পাইথন 2 এবং 3 উভয় ক্ষেত্রেই কাজ করবে:
from bs4 import BeautifulSoup
from bs4.dammit import EncodingDetector
import requests
parser = 'html.parser' # or 'lxml' (preferred) or 'html5lib', if installed
resp = requests.get("http://www.gpsbasecamp.com/national-parks")
http_encoding = resp.encoding if 'charset' in resp.headers.get('content-type', '').lower() else None
html_encoding = EncodingDetector.find_declared_encoding(resp.content, is_html=True)
encoding = html_encoding or http_encoding
soup = BeautifulSoup(resp.content, parser, from_encoding=encoding)
for link in soup.find_all('a', href=True):
print(link['href'])
soup.find_all('a', href=True)
কল সব খুঁজে বের করে <a>
আছে একটি উপাদানhref
অ্যাট্রিবিউট; বৈশিষ্ট্য ব্যতীত উপাদানগুলি এড়িয়ে যায়।
বিউটিউসসপ 3 মার্চ 2012 সালে উন্নয়ন বন্ধ করেছে; নতুন প্রকল্পগুলিতে সর্বদা, বিউটিউসসপ 4 ব্যবহার করা উচিত।
নোট করুন যে আপনার এইচটিএমএলকে বাইট থেকে বিউটিফুলসুপে ডিকোডিং করা উচিত । আপনি characterset HTTP প্রতিক্রিয়া হেডার পাওয়া ডিকোডিং সহায়তা করার BeautifulSoup অবহিত করতে পারেন, কিন্তু এই করতে ভুল এবং একটি সঙ্গে পরস্পরবিরোধী হতে <meta>
হেডারের তথ্য এইচটিএমএল নিজেই পাওয়া যায় নি, যে কারণে উপরে ব্যবহারসমূহ BeautifulSoup অভ্যন্তরীণ বর্গ পদ্ধতিEncodingDetector.find_declared_encoding()
নিশ্চিত করতে যেমন এম্বেড থাকা এনকোডিং ইঙ্গিতগুলি একটি ভুল কনফিগার্ড সার্ভারের উপরে জয়ী হয়।
সাথে requests
, response.encoding
প্রতিক্রিয়ার একটি text/*
মাইমটাইপ থাকলে ল্যাটিন -১ এ অ্যাট্রিবিউটটি ডিফল্ট হয় , এমনকি কোনও অক্ষর ফেরানো না হলেও। এটি এইচটিটিপি আরএফসিগুলির সাথে সামঞ্জস্যপূর্ণ তবে HTML পার্সিংয়ের সাথে ব্যবহারের সময় বেদনাদায়ক তাই charset
কন্টেন্ট-টাইপ শিরোনামে কোনও সেট না করা অবস্থায় আপনার সেই বৈশিষ্ট্যটিকে উপেক্ষা করা উচিত ।
SoupStrainer
মানে? এটি কোথাও যায় নি, এটি এখনও প্রকল্পের অংশ ।
অন্যরা বিউটিফুলসুপের প্রস্তাব দিয়েছেন, তবে lxML ব্যবহার করা আরও ভাল । এর নাম সত্ত্বেও এটি এইচটিএমএল বিশ্লেষণ এবং স্ক্র্যাপ করার জন্য is এটি বিউটিফুলসাপের চেয়ে অনেক দ্রুত এবং এটি এমনকি "ভাঙ্গা" এইচটিএমএলকে বিউটিফুলসাপের (তাদের খ্যাতির দাবি) থেকেও ভাল পরিচালনা করে। আপনি lxML এপিআই শিখতে না চাইলে এটি বিউটিফুলসুপের জন্য একটি সামঞ্জস্যতা এপিআই রয়েছে
বিউটিফুলসপ ব্যবহার করার আর কোনও কারণ নেই, যদি না আপনি গুগল অ্যাপ ইঞ্জিনে বা এমন কিছু হন যেখানে নিখুঁতভাবে পাইথনের অনুমতি নেই।
lxML.html CSS3 নির্বাচনকারীদেরও সমর্থন করে যাতে এই ধরণের জিনিসটি তুচ্ছ।
LxML এবং xpath সহ একটি উদাহরণটি দেখতে পাবেন:
import urllib
import lxml.html
connection = urllib.urlopen('http://www.nytimes.com')
dom = lxml.html.fromstring(connection.read())
for link in dom.xpath('//a/@href'): # select the url in href for all a tags(links)
print link
lxml
ইনস্টল করা থাকলে ডিফল্ট পার্সার হিসাবে ব্যবহার করবে ।
import urllib2
import BeautifulSoup
request = urllib2.Request("http://www.gpsbasecamp.com/national-parks")
response = urllib2.urlopen(request)
soup = BeautifulSoup.BeautifulSoup(response)
for a in soup.findAll('a'):
if 'national-park' in a['href']:
print 'found a url with national-park in the link'
নিম্নলিখিত পৃষ্ঠাগুলি ব্যবহার করে ওয়েব পৃষ্ঠায় উপলব্ধ সমস্ত লিঙ্কগুলি পুনরুদ্ধার করতে হবে urllib2
এবং BeautifulSoup4
:
import urllib2
from bs4 import BeautifulSoup
url = urllib2.urlopen("http://www.espncricinfo.com/").read()
soup = BeautifulSoup(url)
for line in soup.find_all('a'):
print(line.get('href'))
হুডের নীচে বিউটিফুলসপ এখন lxML ব্যবহার করে। অনুরোধ, lxML এবং তালিকা অনুধাবন একটি ঘাতক কম্বো তৈরি করে।
import requests
import lxml.html
dom = lxml.html.fromstring(requests.get('http://www.nytimes.com').content)
[x for x in dom.xpath('//a/@href') if '//' in x and 'nytimes.com' not in x]
তালিকার কমপ্লেক্সে, "if '//' এবং 'url.com' x নয়," সাইটের 'অভ্যন্তরীণ' নেভিগেশন ইউআরএল ইত্যাদির url তালিকা স্ক্রাব করার একটি সহজ পদ্ধতি method
কেবলমাত্র বিসুপ এবং রেজিেক্স ছাড়াই লিঙ্কগুলি পাওয়ার জন্য:
import urllib2
url="http://www.somewhere.com"
page=urllib2.urlopen(url)
data=page.read().split("</a>")
tag="<a href=\""
endtag="\">"
for item in data:
if "<a href" in item:
try:
ind = item.index(tag)
item=item[ind+len(tag):]
end=item.index(endtag)
except: pass
else:
print item[:end]
আরও জটিল ক্রিয়াকলাপের জন্য অবশ্যই বিএসউপ এখনও পছন্দসই।
<a
এবং এর মধ্যে কিছু আছে href
? বলুন rel="nofollow"
বা onclick="..."
এমনকি একটি নতুন লাইন? stackoverflow.com/questions/1732348/...
এই স্ক্রিপ্টটি যা আপনার সন্ধান করছে তা করে তবে নিখুঁত লিঙ্কগুলির সাথে সম্পর্কিত লিঙ্কগুলিও সমাধান করে।
import urllib
import lxml.html
import urlparse
def get_dom(url):
connection = urllib.urlopen(url)
return lxml.html.fromstring(connection.read())
def get_links(url):
return resolve_links((link for link in get_dom(url).xpath('//a/@href')))
def guess_root(links):
for link in links:
if link.startswith('http'):
parsed_link = urlparse.urlparse(link)
scheme = parsed_link.scheme + '://'
netloc = parsed_link.netloc
return scheme + netloc
def resolve_links(links):
root = guess_root(links)
for link in links:
if not link.startswith('http'):
link = urlparse.urljoin(root, link)
yield link
for link in get_links('http://www.google.com'):
print link
সমস্ত লিঙ্কগুলি সন্ধানের জন্য, আমরা এই উদাহরণে পুনরায় মডুলের সাথে urllib2 মডিউলটি ব্যবহার করব * রে মডিউলের অন্যতম শক্তিশালী ফাংশন হ'ল "re.findall ()"। যখন রি-সার্চ () কোনও প্যাটার্নের জন্য প্রথম ম্যাচটি সন্ধান করতে ব্যবহৃত হয়, তখনই রিফাইন্ডল () সমস্ত মিলখুঁজে পায়এবং স্ট্রিংগুলির একটি তালিকা হিসাবে তাদের প্রতিটি স্ট্রিংকে একটি করে ম্যাচ উপস্থাপন করে প্রদর্শিত করে *
import urllib2
import re
#connect to a URL
website = urllib2.urlopen(url)
#read html code
html = website.read()
#use re.findall to get all the links
links = re.findall('"((http|ftp)s?://.*?)"', html)
print links
নিয়মিত এক্সপ্রেশন কেন ব্যবহার করবেন না:
import urllib2
import re
url = "http://www.somewhere.com"
page = urllib2.urlopen(url)
page = page.read()
links = re.findall(r"<a.*?\s*href=\"(.*?)\".*?>(.*?)</a>", page)
for link in links:
print('href: %s, HTML text: %s' % (link[0], link[1]))
(r"<a.*?\s*href=\"(.*?)\".*?>(.*?)</a>", page)
অর্থ খুঁজে পেতে পারি ? ধন্যবাদ!
লিঙ্কগুলি বিভিন্ন বৈশিষ্ট্যের মধ্যে থাকতে পারে যাতে আপনি নির্বাচন করতে সেই বৈশিষ্ট্যগুলির একটি তালিকা পাস করতে পারেন
উদাহরণস্বরূপ, src এবং href অ্যাট্রিবিউট (এখানে আমি ^ অপারেটর দিয়ে শুরুটি ব্যবহার করছি এটি নির্দিষ্ট করার জন্য যে এই বৈশিষ্ট্যগুলির মানগুলির কোনওটি http দিয়ে শুরু হয় required আপনি এটি প্রয়োজনীয় হিসাবে উপযুক্ত করতে পারেন
from bs4 import BeautifulSoup as bs
import requests
r = requests.get('https://stackoverflow.com/')
soup = bs(r.content, 'lxml')
links = [item['href'] if item.get('href') is not None else item['src'] for item in soup.select('[href^="http"], [src^="http"]') ]
print(links)
[ATTR ^ = VALUE]
অ্যাটারের একটি গুণবাচক নাম সহ এমন উপাদানগুলিকে পুনঃস্থাপন করে যার মান দ্বারা মান পূর্বনির্ধারিত (পূর্ববর্তী) হয়।
এখানে @ars গৃহীত উত্তর এবং ব্যবহার একটি উদাহরণ BeautifulSoup4
, requests
এবং wget
মডিউল ডাউনলোডসমূহ হ্যান্ডেল করতে।
import requests
import wget
import os
from bs4 import BeautifulSoup, SoupStrainer
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/eeg-mld/eeg_full/'
file_type = '.tar.gz'
response = requests.get(url)
for link in BeautifulSoup(response.content, 'html.parser', parse_only=SoupStrainer('a')):
if link.has_attr('href'):
if file_type in link['href']:
full_path = url + link['href']
wget.download(full_path)
নীচের সংশোধন করার পরে @ ব্লেয়ারগ 23 কাজ করে আমি উত্তর পেয়েছি (যেখানে এটি সঠিকভাবে কাজ করতে ব্যর্থ হয়েছে সেই দৃশ্যের আবরণ):
for link in BeautifulSoup(response.content, 'html.parser', parse_only=SoupStrainer('a')):
if link.has_attr('href'):
if file_type in link['href']:
full_path =urlparse.urljoin(url , link['href']) #module urlparse need to be imported
wget.download(full_path)
পাইথন 3 এর জন্য:
urllib.parse.urljoin
পরিবর্তে সম্পূর্ণ URL টি পেতে ব্যবহার করতে হবে।
বিটিফুলসুপের নিজস্ব পার্সার ধীর হতে পারে। Lxml ব্যবহার করা আরও সম্ভাব্য হতে পারে যা ইউআরএল থেকে সরাসরি পার্স করতে সক্ষম (নীচে বর্ণিত কিছু সীমাবদ্ধতা সহ)।
import lxml.html
doc = lxml.html.parse(url)
links = doc.xpath('//a[@href]')
for link in links:
print link.attrib['href']
উপরের কোডগুলি লিঙ্কগুলি যেমন আছে তেমন ফিরিয়ে দেবে এবং বেশিরভাগ ক্ষেত্রে তারা সাইটের মূল থেকে আপেক্ষিক লিঙ্ক বা পরম হবে। যেহেতু আমার ব্যবহারের ক্ষেত্রে কেবলমাত্র একটি নির্দিষ্ট ধরণের লিঙ্কগুলিই বের করা ছিল, নীচে এমন একটি সংস্করণ যা লিঙ্কগুলিকে পুরো ইউআরএলগুলিতে রূপান্তর করে এবং যা বৈকল্পিকভাবে একটি গ্লোব প্যাটার্ন গ্রহণ করে *.mp3
। এটি যদিও আপেক্ষিক পথে একক এবং দ্বৈত বিন্দু পরিচালনা করবে না, তবে এখনও পর্যন্ত আমার এটির প্রয়োজন হয়নি। আপনি পার্স URL রয়েছে টুকরা করার প্রয়োজন হলে ../
বা ./
তারপর urlparse.urljoin উপকারে লাগতে পারে।
দ্রষ্টব্য : ডাইরেক্ট lxML url পার্সিং লোডিং হ্যান্ডেল করে না https
এবং পুনর্নির্দেশগুলি করে না, সুতরাং এই কারণে নীচের সংস্করণটি urllib2
+ ব্যবহার করছে lxml
।
#!/usr/bin/env python
import sys
import urllib2
import urlparse
import lxml.html
import fnmatch
try:
import urltools as urltools
except ImportError:
sys.stderr.write('To normalize URLs run: `pip install urltools --user`')
urltools = None
def get_host(url):
p = urlparse.urlparse(url)
return "{}://{}".format(p.scheme, p.netloc)
if __name__ == '__main__':
url = sys.argv[1]
host = get_host(url)
glob_patt = len(sys.argv) > 2 and sys.argv[2] or '*'
doc = lxml.html.parse(urllib2.urlopen(url))
links = doc.xpath('//a[@href]')
for link in links:
href = link.attrib['href']
if fnmatch.fnmatch(href, glob_patt):
if not href.startswith(('http://', 'https://' 'ftp://')):
if href.startswith('/'):
href = host + href
else:
parent_url = url.rsplit('/', 1)[0]
href = urlparse.urljoin(parent_url, href)
if urltools:
href = urltools.normalize(href)
print href
ব্যবহার নিম্নলিখিত:
getlinks.py http://stackoverflow.com/a/37758066/191246
getlinks.py http://stackoverflow.com/a/37758066/191246 "*users*"
getlinks.py http://fakedomain.mu/somepage.html "*.mp3"
lxml
শুধুমাত্র বৈধ ইনপুট পরিচালনা করতে পারে, এটি কীভাবে প্রতিস্থাপন করতে পারে BeautifulSoup
?
lxml.html
চেয়ে কিছুটা বেশি হালকা lxml.etree
। যদি আপনার ইনপুটটি সুগঠিত না হয় তবে আপনি স্পষ্টতই বিউটিফুলসুফ পার্সার সেট করতে পারেন: lxML.de/eitionsoup.html । এবং আপনি যদি বিটিফুলসপ দিয়ে যান তবে বিএস 3 আরও ভাল পছন্দ।
import urllib2
from bs4 import BeautifulSoup
a=urllib2.urlopen('http://dir.yahoo.com')
code=a.read()
soup=BeautifulSoup(code)
links=soup.findAll("a")
#To get href part alone
print links[0].attrs['href']
বহিরাগত এবং অভ্যন্তরীণ উভয় লিঙ্কের সাথে এক সাথে অনেকগুলি নকল লিঙ্ক থাকতে পারে। দুজনের মধ্যে পার্থক্য করতে এবং সেট ব্যবহার করে অনন্য লিঙ্কগুলি পান:
# Python 3.
import urllib
from bs4 import BeautifulSoup
url = "http://www.espncricinfo.com/"
resp = urllib.request.urlopen(url)
# Get server encoding per recommendation of Martijn Pieters.
soup = BeautifulSoup(resp, from_encoding=resp.info().get_param('charset'))
external_links = set()
internal_links = set()
for line in soup.find_all('a'):
link = line.get('href')
if not link:
continue
if link.startswith('http'):
external_links.add(link)
else:
internal_links.add(link)
# Depending on usage, full internal links may be preferred.
full_internal_links = {
urllib.parse.urljoin(url, internal_link)
for internal_link in internal_links
}
# Print all unique external and full internal links.
for link in external_links.union(full_internal_links):
print(link)