質問

Python を使用して Web ページのリンクを取得し、リンクの URL アドレスをコピーするにはどうすればよいですか?

役に立ちましたか?

解決

ここでBeautifulSoupでSoupStrainerクラスを使用して、短い抜粋です。

import httplib2
from BeautifulSoup 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'])

BeautifulSoupのドキュメントでは、実際には非常に良好で、一般的なシナリオの数をカバーしています:

http://www.crummy.com/software/BeautifulSoup/documentation.html

編集:あなたは、事前に解析しているものを知っていれば、それは、もう少し効率的(メモリと速度的に)ですので、私はSoupStrainerクラスを使用していることに注意してください。

他のヒント

完全酒、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'])

とPython 2と3の両方で動作するように書かれた requestsライブラリに、使用バージョン:

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)コールが<a>属性を持つすべてのhref要素を見つけました。属性のない要素はスキップされます。

BeautifulSoup 3は、2012年3月に開発を停止しました。新しいプロジェクトは、本当にいつも、BeautifulSoup 4を使用する必要があります。

BeautifulSoup のには、をバイトからHTMLをデコード残す必要があることに注意してください。あなたは、デコードを支援するためにHTTPレスポンスヘッダで見つかったキャラクタのBeautifulSoupを知らせることができますが、これはは上記が使用する理由であるHTML自体で見つかった<meta>ヘッダ情報、と間違っていると競合することができこのよう埋め込まれたエンコードのヒントが誤って設定サーバーに勝つことを確認するために内部クラスメソッドEncodingDetector.find_declared_encoding() BeautifulSoupます。

応答がrequestsのMIMEタイプを持っている場合は、

response.encodingで、text/*にはキャラクタが返されなかった場合でも、ラテン-1にデフォルト値を属性。 HTMLの解析で使用した場合これは、HTTPのRFCのと一致しますが、痛みを伴うので、何charsetがContent-Typeヘッダに設定されていないときは、その属性を無視しなければならない。

他の人はBeautifulSoupを推奨していますが、それを使用する方がはるかに優れています lxml. 。その名前にもかかわらず、HTML の解析とスクレイピングにも使用されます。これは BeautifulSoup よりもはるかに高速で、「壊れた」HTML も BeautifulSoup (彼らの名声) よりもうまく処理します。lxml API を学びたくない場合は、BeautifulSoup との互換性 API もあります。

イアン・ブリック氏も同意.

Google App Engine など純粋に Python 以外のものが許可されていない場合を除き、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
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'

次のコードは、urllib2BeautifulSoup4を使用してWebページで利用可能なすべてのリンクを取得するには、次のとおりです。

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は今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リストをスクラブするための簡単な方法です。

すべてのリンクを見つけるために、この例ではre.moduleとともにurllib2モジュールを使用します*re モジュールの最も強力な関数の 1 つは「re.findall()」です。re.search() はパターンの最初の一致を見つけるために使用されますが、 re.findall() は 全て一致したものを文字列のリストとして返します。各文字列は 1 つの一致を表します*

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

ちょうど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が依然として好ましい。

なぜ正規表現を使用しています:

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

このスクリプトは、あなたが探して何が、しかし、また、絶対リンクへの相対リンクを解決します。

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
あなたが選択するために、これらの属性のリストを渡すことができるように

リンクは、さまざまな属性内とすることができる。

例えば、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受け入れ答えとダウンロードを処理するBeautifulSoup4requests、および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を取得するために使用する必要があります。

BeatifulSoup 独自のパーサーは遅い場合があります。を使用したほうが現実的かもしれません lxml URL から直接解析できます (後述するいくつかの制限があります)。

import lxml.html

doc = lxml.html.parse(url)

links = doc.xpath('//a[@href]')

for link in links:
    print link.attrib['href']

上記のコードはリンクをそのまま返します。ほとんどの場合、リンクはサイト ルートからの相対リンクまたは絶対リンクになります。私のユースケースは特定のタイプのリンクのみを抽出することであったため、以下はリンクを完全な URL に変換し、オプションで次のような glob パターンを受け入れるバージョンです。 *.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"
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']
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top