Pythonのurllib2は、3xxリダイレクトに従って、最終的なコンテンツを取得します。urllib2(またはhttplib2などの他のライブラリ)もメタ更新に従うようにする方法はありますか?または、更新メタタグのHTMLを手動で解析する必要がありますか?
10331 次
5 に答える
12
BeautifulSoupとhttplib2(および証明書ベースの認証)を使用したソリューションは次のとおりです。
import BeautifulSoup
import httplib2
def meta_redirect(content):
soup = BeautifulSoup.BeautifulSoup(content)
result=soup.find("meta",attrs={"http-equiv":"Refresh"})
if result:
wait,text=result["content"].split(";")
if text.strip().lower().startswith("url="):
url=text[4:]
return url
return None
def get_content(url, key, cert):
h=httplib2.Http(".cache")
h.add_certificate(key,cert,"")
resp, content = h.request(url,"GET")
# follow the chain of redirects
while meta_redirect(content):
resp, content = h.request(meta_redirect(content),"GET")
return content
于 2010-09-08T14:30:59.203 に答える
4
リクエストとlxmlライブラリを使用した同様のソリューション。また、テスト対象が実際にHTMLであることを簡単にチェックします(私の実装の要件)。また、リクエストライブラリのセッションを使用してCookieをキャプチャして使用することもできます(リダイレクト+ Cookieがスクレイピング防止メカニズムとして使用されている場合は必要になることがあります)。
import magic
import mimetypes
import requests
from lxml import html
from urlparse import urljoin
def test_for_meta_redirections(r):
mime = magic.from_buffer(r.content, mime=True)
extension = mimetypes.guess_extension(mime)
if extension == '.html':
html_tree = html.fromstring(r.text)
attr = html_tree.xpath("//meta[translate(@http-equiv, 'REFSH', 'refsh') = 'refresh']/@content")[0]
wait, text = attr.split(";")
if text.lower().startswith("url="):
url = text[4:]
if not url.startswith('http'):
# Relative URL, adapt
url = urljoin(r.url, url)
return True, url
return False, None
def follow_redirections(r, s):
"""
Recursive function that follows meta refresh redirections if they exist.
"""
redirected, url = test_for_meta_redirections(r)
if redirected:
r = follow_redirections(s.get(url), s)
return r
使用法:
s = requests.session()
r = s.get(url)
# test for and follow meta redirects
r = follow_redirections(r, s)
于 2013-06-04T19:52:43.620 に答える
1
OK、ライブラリがそれをサポートしていないようですので、私はこのコードを使用しています:
import urllib2
import urlparse
import re
def get_hops(url):
redirect_re = re.compile('<meta[^>]*?url=(.*?)["\']', re.IGNORECASE)
hops = []
while url:
if url in hops:
url = None
else:
hops.insert(0, url)
response = urllib2.urlopen(url)
if response.geturl() != url:
hops.insert(0, response.geturl())
# check for redirect meta tag
match = redirect_re.search(response.read())
if match:
url = urlparse.urljoin(url, match.groups()[0].strip())
else:
url = None
return hops
于 2010-02-27T01:27:26.243 に答える
1
bs4を使用したくない場合は、次のようにlxmlを使用できます。
from lxml.html import soupparser
def meta_redirect(content):
root = soupparser.fromstring(content)
result_url = root.xpath('//meta[@http-equiv="refresh"]/@content')
if result_url:
result_url = str(result_url[0])
urls = result_url.split('URL=') if len(result_url.split('url=')) < 2 else result_url.split('url=')
url = urls[1] if len(urls) >= 2 else None
else:
return None
return url
于 2017-02-13T07:42:59.103 に答える
-1
BeautifulSoupまたはlxmlを使用してHTMLを解析します。
于 2010-02-23T13:39:04.077 に答える