जवाबों:
यहां सुंदरसुपर में सूपस्ट्रेनर क्लास का उपयोग करते हुए एक छोटा सा स्निपेट दिया गया है:
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
और यह काम करता है।
संपूर्णता के लिए, BeautifulSoup 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 एस का उपयोग करना चाहिए, हमेशा।
ध्यान दें कि आपको HTML को बाइट्स से सुंदरसुपर को डिकोड करना छोड़ना चाहिए । डिकोडिंग में सहायता करने के लिए आप HTTP रिस्पांस हेडर में पाए जाने वाले कैरेक्टरसेट के ब्यूटीफुलस को सूचित कर सकते हैं, लेकिन यह गलत हो सकता है और <meta>
HTML में पाए जाने वाले हेडर की जानकारी के साथ परस्पर विरोधी हो सकता है, यही कारण है कि उपरोक्त सुंदरसेप आंतरिक वर्ग विधि EncodingDetector.find_declared_encoding()
का उपयोग यह सुनिश्चित करने के लिए करता है कि ऐसे एम्बेडेड एन्कोडिंग संकेत एक गलत सर्वर पर जीतते हैं।
साथ requests
, response.encoding
लैटिन -1 के लिए विशेषता चूक प्रतिक्रिया एक है, तो text/*
भले ही कोई characterset वापस आ गया था माइम प्रकार,। यह एचटीटीपी RFC के अनुरूप है, लेकिन HTML पार्सिंग के साथ प्रयोग करने पर दर्दनाक है, इसलिए आपको उस विशेषता को अनदेखा कर देना चाहिए, जब charset
कंटेंट-टाइप हेडर में कोई सेट नहीं है।
SoupStrainer
आपका मतलब है? यह कहीं नहीं गया, यह अभी भी परियोजना का हिस्सा है ।
दूसरों ने ब्यूटीफुल की सिफारिश की है, लेकिन यह एलएक्सएमएल का उपयोग करना बेहतर है । अपने नाम के बावजूद, यह HTML को पार्स और स्क्रैप करने के लिए भी है। यह सुंदरसुपर की तुलना में बहुत तेज है, और यह सुंदरसुपर (उनकी प्रसिद्धि के दावे) की तुलना में बेहतर "टूटे हुए" HTML को भी संभालता है। अगर आप lxml API सीखना नहीं चाहते हैं तो भी BeautifulSoup के लिए कम्पैटिबिलिटी API है।
जब तक आप Google App Engine पर नहीं होते हैं या ऐसा कुछ भी नहीं होता है, जहां BeautifulSoup का उपयोग करने का कोई कारण नहीं है, तो कुछ भी नहीं है जो कि विशुद्ध रूप से अजगर की अनुमति नहीं है।
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
अगर स्थापित किया गया है तो सुंदर 4 डिफ़ॉल्ट डिफ़ॉल्ट पार्सर के रूप में उपयोग करेगा ।
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]
सूची COMP में, "if '//' और 'url.com' x में नहीं ', साइटों की' आंतरिक 'नेविगेशन url, आदि की url सूची को साफ़ करने का एक सरल तरीका है।
बस लिंक प्राप्त करने के लिए, बिना बी। एस.एस.पी. और रेगेक्स:
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
सभी लिंक खोजने के लिए, हम इस उदाहरण में re.module * के साथ urllib2 मॉड्यूल का उपयोग करेंगे * पुन: मॉड्यूल में सबसे शक्तिशाली फ़ंक्शन में से एक "re.findall ()" है। जबकि re.search () का उपयोग पैटर्न के लिए पहला मैच खोजने के लिए किया जाता है, 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 से शुरू होती है। आप इसे आवश्यकतानुसार दर्जी कर सकते हैं।
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 ^ = मूल्य]
तत्वों को विशेषता के नाम का प्रतिनिधित्व करता है attr जिसका मान मूल्य से पहले (उपसर्ग) है।
यहाँ @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)
मुझे निम्नलिखित सुधार के बाद @ Blairg23 द्वारा काम करने का उत्तर मिला, (उस परिदृश्य को कवर करना जहां यह सही ढंग से काम करने में विफल रहा):
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 का उपयोग करने के लिए अधिक संभव हो सकता है जो URL से सीधे पार्स करने में सक्षम है (नीचे दी गई कुछ सीमाओं के साथ)।
import lxml.html
doc = lxml.html.parse(url)
links = doc.xpath('//a[@href]')
for link in links:
print link.attrib['href']
ऊपर दिए गए कोड लिंक को वापस कर देंगे, और अधिकांश मामलों में वे साइट रूट से संबंधित लिंक या निरपेक्ष होंगे। चूंकि मेरा उपयोग मामला केवल एक निश्चित प्रकार के लिंक निकालने के लिए था, नीचे एक संस्करण है जो लिंक को पूर्ण URL में परिवर्तित करता है और जो वैकल्पिक रूप से एक ग्लोब पैटर्न को स्वीकार करता है *.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
। यदि आपका इनपुट अच्छी तरह से नहीं बना है, तो आप स्पष्ट रूप से BeautifulSoup parser: lxml.de/elements.p.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)