如何檢索網頁的鏈接並使用Python複製鏈接的url地址?使用python和BeautifulSoup從網頁檢索鏈接
回答
下面是一個使用SoupStrainer類BeautifulSoup其中一小段:
import httplib2
from BeautifulSoup import BeautifulSoup, SoupStrainer
http = httplib2.Http()
status, response = http.request('http://www.nytimes.com')
for link in BeautifulSoup(response, parseOnlyThese=SoupStrainer('a')):
if link.has_attr('href'):
print link['href']
的BeautifulSoup文檔還算是不錯的,並且涵蓋了許多典型場景:
http://www.crummy.com/software/BeautifulSoup/documentation.html
編輯:請注意,我使用了SoupStrainer類,因爲它更高效(內存和速度方面),如果你知道你在解析什麼 提前。
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'
只是爲了得到鏈接,沒有B.soup和正則表達式:
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]
對於更復雜的操作,當然BSoup的仍然是首選。
其他人推薦BeautifulSoup,但使用lxml要好得多。儘管它的名字,它也用於解析和刮取HTML。它比BeautifulSoup快得多,它甚至比BeautifulSoup(他們的聲望)更好地處理「破碎的」HTML。如果您不想學習lxml API,它也具有用於BeautifulSoup的兼容性API。
沒有理由再使用BeautifulSoup,除非您使用的是Google App Engine或其他任何不是純粹Python不允許的東西。
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
爲什麼不使用正則表達式:
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]))
引擎蓋下BeautifulSoup現在使用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]
在列表排版中,「如果‘//’和‘url.com’不在x」是一個簡單的方法來擦洗站點「內部」導航URL等等的URL列表
以下代碼是檢索所有使用的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'))
爲了完整起見,BeautifulSoup版本4在網頁中的可用鏈路,利用由服務器提供的,以及所述編碼的:
from bs4 import BeautifulSoup
import urllib2
resp = urllib2.urlopen("http://www.gpsbasecamp.com/national-parks")
soup = BeautifulSoup(resp, from_encoding=resp.info().getparam('charset'))
for link in soup.find_all('a', href=True):
print link['href']
或Python的3版本:
from bs4 import BeautifulSoup
import urllib.request
resp = urllib.request.urlopen("http://www.gpsbasecamp.com/national-parks")
soup = BeautifulSoup(resp, from_encoding=resp.info().get_param('charset'))
for link in soup.find_all('a', href=True):
print(link['href'])
以及使用該requests
library,其爲寫在版本將在兩個Python 2和3工作:
from bs4 import BeautifulSoup
from bs4.dammit import EncodingDetector
import requests
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, from_encoding=encoding)
for link in soup.find_all('a', href=True):
print(link['href'])
的soup.find_all('a', href=True)
呼叫發現具有href
屬性的所有<a>
元件;沒有屬性的元素被跳過。
BeautifulSoup 3於2012年3月停止開發;新項目真的應該永遠使用BeautifulSoup 4。
請注意,您應該將HTML從字節解碼爲BeautifulSoup。您可以通知BeautifulSoup HTTP響應頭文件中找到的字符集來協助解碼,但是這個可能是是錯誤的,並且與在HTML本身中找到的<meta>
標頭信息衝突,這就是爲什麼上面使用BeautifulSoup內部類方法EncodingDetector.find_declared_encoding()
以確保這種嵌入式編碼提示勝過錯誤配置的服務器。
使用requests
時,即使未返回任何字符集,如果響應具有text/*
mimetype,response.encoding
屬性將默認爲拉丁-1。這與HTTP RFC一致,但與HTML解析一起使用時很痛苦,所以如果Content-Type標頭中沒有設置charset
,應該忽略該屬性。
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']
這個腳本是做你要找的,但也解決了絕對鏈接的相對鏈接。
要找到所有的聯繫,我們將在這個例子中使用的urllib2模塊一起 與re.module *一重模塊中功能最強大的是「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
BeatifulSoup自己的解析器可能會很慢。使用能夠直接從URL進行解析的lxml可能更爲可行(有一些下面提到的限制)。上述
import lxml.html
doc = lxml.html.parse(url)
links = doc.xpath('//a[@href]')
for link in links:
print link.attrib['href']
的代碼將返回鏈接的是,在大多數情況下,他們會從站點根目錄相對鏈接或絕對的。由於我的使用案例只是提取某種類型的鏈接,因此下面是一個版本,可將鏈接轉換爲完整的URL,並可選擇接受像*.mp3
這樣的glob模式。它不會處理相對路徑中的單點和雙點,但到目前爲止,我並不需要它。如果您需要解析包含../
或./
的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"
下面是使用requests
接受的答案@ars和BeautifulSoup4
,和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)
對於Python 3:
urllib.parse.urljoin
有用於獲取完整的URL。
- 1. 使用Beautifulsoup和Selen從某個網頁獲取鏈接
- 2. 所有未從網頁檢索的鏈接 - python
- 3. 試圖從網頁抓取使用BeautifulSoup的絕對鏈接
- 4. 使用python和beautifulsoup搜索解析的網頁時出錯
- 5. 網頁抓取兩個HTML文本和圖像鏈接使用Python Beautifulsoup
- 6. 無法使用BeautifulSoup檢索谷歌搜索結果頁面上的鏈接
- 7. 使用urllib和BeautifulSoup從Python中檢索信息
- 8. 使用Python和BeautifulSoup從網頁下載.xls文件
- 9. 用BeautifulSoup和Python刮取Javascript網頁
- 10. 如何使用lxml,XPath和Python從網頁中提取鏈接?
- 11. 使用python beautifulsoup進行網頁爬蟲
- 12. Python腳本使用beautifulSoup湊網頁
- 13. 使用BeautifulSoup進行網頁掃描 - Python
- 14. 如何使用Jsoup從網站上的鏈接檢索網址?
- 15. 使用BeautifulSoup查找網頁中的某個鏈接
- 16. 從頁面檢索所有信息BeautifulSoup
- 17. Python/BeautifulSoup:從網頁上颳去數據
- 18. Python/BeautifulSoup:檢索'href'屬性
- 19. 點擊鏈接與Python BeautifulSoup
- 20. Python無法從網頁獲取鏈接
- 21. 拉鍊接和刮python這些網頁
- 22. 從Python和Beautifulsoup
- 23. 使用Python中的BeautifulSoup從超鏈接中獲取URL
- 24. 使用Jquery檢索鏈接
- 25. 使用jquery檢索鏈接
- 26. 使用beautifulsoup和python
- 27. 如何找到鏈接和修改使用BeautifulSoup的HTML Python中
- 28. 無法使用硒和python檢索HTML表格中的鏈接
- 29. 使用selenium,beautifulsoup和python進行網頁掃描
- 30. 無法使用python和beautifulsoup在網頁中抓取某些href
+1,使用過濾器是一個好主意,因爲它允許你繞過大量的不必要的解析,當你所有的時候都是鏈接。 – 2009-07-03 18:57:34
在我看到Evan的評論之前,我編輯添加了類似的解釋。不過謝謝你的注意! – ars 2009-07-03 19:01:16
謝謝,這解決了我的問題,用這個我完成了我的項目,非常感謝 – NepUS 2009-07-03 21:17:57