# urllibを使用
# リクエストを送信
# 1. urlopen
import urllib.request
response = urllib.request.urlopen('https://www.python.org')
#print(response.read().decode('utf-8'))
# typeメソッドを利用してレスポンスのタイプを出力
print(type(response))
print(response.status)
print(response.getheaders())
print(response.getheader('Sercer'))
# パラメータを渡す
# urllib.request.urlopen(url, data=None, [timeout,]*, cafile=None, capath=None, cadefault=False, context=None)
# dataパラメータはオプションです。このパラメータを追加する場合は、bytesメソッドを使用してパラメータをバイトストリームエンコーディング形式の内容、つまりbytes型に変換する必要があります
# また、このパラメータを渡すと、リクエストの方法はGET方式ではなく、POST方式になります
# ここでリクエストするサイトはhttpbin.orgで、HTTPリクエストのテストを提供します
import urllib.parse
data = bytes(urllib.parse.urlencode({'word':'hello'}),encoding = 'utf8')
response = urllib.request.urlopen('http://httpbin.org/post',data=data)
print(response.read())
b'{\n "args": {}, \n "data": "", \n "files": {}, \n "form": {\n "word": "hello"\n }, \n "headers": {\n "Accept-Encoding": "identity", \n "Content-Length": "10", \n "Content-Type": "application/x-www-form-urlencoded", \n "Host": "httpbin.org", \n "User-Agent": "Python-urllib/3.12", \n "X-Amzn-Trace-Id": "Root=1-67c1704f-4eb3a4ac2b4e81cb47c01cfc"\n }, \n "json": null, \n "origin": "154.40.60.12", \n "url": "http://httpbin.org/post"\n}\n'
# タイムアウト時間を設定して、ウェブページが長時間応答しない場合は、その取得をスキップします
import socket
import urllib.error
try:
response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
except urllib.error.URLError as e:
if isinstance(e.reason, socket.timeout):
print('タイムアウト')
# 2. リクエスト
# class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
# 必須パラメータurl dataは型を渡す必要があり、インスタンスadd_header()を呼び出してheadersパラメータを追加します
import urllib.request
request = urllib.request.Request('https://python.org')
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))
from urllib import parse,request
url = 'http://httpbin.org/post'
headers = {'User-Agent':'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)','Host':'httpbin.org'}
dict = {'name':'Germey'}
data = bytes(parse.urlencode(dict),encoding='utf8')
req = request.Request(url,data=data,headers=headers,method='POST')
response = request.urlopen(req)
print(response.read().decode('utf-8'))
{
"args": {},
"data": "",
"files": {},
"form": {
"name": "Germey"
},
"headers": {
"Accept-Encoding": "identity",
"Content-Length": "11",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)",
"X-Amzn-Trace-Id": "Root=1-67c17458-6ec1e2f400a80e126995c7e6"
},
"json": null,
"origin": "154.40.60.12",
"url": "http://httpbin.org/post"
}
# 3. 高度な使用法
# 様々なハンドラーがあり、ログイン認証を処理するもの、Cookiesを処理するもの、プロキシ設定を処理するものがあります
# urllib.requestモジュールのBaseHandlerクラスは、他のすべてのハンドラーの親クラスで、最も基本的なメソッドを提供します。例えば、default_open、protocol_requestなど
# もう一つ重要なクラスはOpenerDirectorで、これをOpenerと呼ぶことができます。簡単に言えば、ハンドラーを利用してオープナーを構築します
# HTTPBasicAuthHandlerは認証を管理します。リンクを開くときに認証が必要な場合は、これを使用して認証の問題を解決できます
from urllib.request import HTTPPasswordMgrWithDefaultRealm,HTTPBasicAuthHandler,build_opener
from urllib.error import URLError
username = 'admin'
password = '*******'
url = 'http://127.0.0.1:5244/'
p =HTTPPasswordMgrWithDefaultRealm()
p.add_password(None,url,username,password)
auth_handler = HTTPBasicAuthHandler()
opener = build_opener(auth_handler)
try:
result = opener.open(url)
html = result.read().decode('utf-8')
print(html)
except URLError as e:
print(e.reason)
# プロキシ、快プロキシを例に
from urllib.request import ProxyHandler
import requests
api = "https://dps.kdlapi.com/api/getdps"
# リクエストパラメータ
params = {
"secret_id": "あなたのid",
"signature": "あなたの署名",
"num": 1, # 抽出数量
}
# レスポンス内容を取得
response = requests.get(api, params=params)
# プロキシIPを解析
proxy_ip = response.text.strip() # 余分な空白文字と改行を削除
# 有効なプロキシIPが取得できたか確認
if not proxy_ip:
print("有効なプロキシIPが取得できませんでした")
else:
# プロキシを定義
username = "*******" # あなたのユーザー名に置き換えてください
password = "*******" # あなたのパスワードに置き換えてください
proxy = f"https://{username}:{password}@{proxy_ip}"
print(f"取得したプロキシIP: {proxy_ip}")
# ProxyHandlerを作成
proxy_handler = urllib.request.ProxyHandler({'http': proxy, 'https': proxy})
# openerを作成
opener = urllib.request.build_opener(proxy_handler)
try:
response = opener.open('https://www.baidu.com')
print(response.read().decode('utf-8'))
except URLError as e:
print(e.reason)
取得したプロキシIP: 218.95.37.135:40358
<html>
<head>
<script>
location.replace(location.href.replace("https://","http://"));
</script>
</head>
<body>
<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>
# Cookies
# ウェブサイトのCookiesを取得する
import http.cookiejar,urllib.request
# CookieJarオブジェクトを宣言
cookie = http.cookiejar.CookieJar()
# HTTPCookieProcessorを利用してハンドラーを構築
handler = urllib.request.HTTPCookieProcessor(cookie)
# build_openerメソッドを利用してオープナーを構築し、open関数を実行
opener = urllib.request.build_opener(handler)
response = opener.open('https://www.baidu.com')
for item in cookie:
print(item.name+"="+item.value)
BD_NOT_HTTPS=1
BIDUPSID=BFE0F5D5293A45F6AEC0BA9BA07B81DA
PSTM=1740734698
BAIDUID=BFE0F5D5293A45F6457A648A94C15082:FG=1
# Cookiesをテキスト形式で保存
filename = 'cookies.txt'
# CookieJarはMozillaCookieJarに変更し、Cookiesとファイル関連のイベントを処理します
cookie = http.cookiejar.MozillaCookieJar(filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
cookie.save(ignore_discard=True, ignore_expires=True)
# 例外を処理
# 1. URLError
from urllib import request,error
try:
response = request.urlopen('https://cuiqingcai.com/index.htm')
except error.URLError as e:
print(e.reason)
見つかりません
# 2. HTTPError
try:
response = request.urlopen('https://cuiqingcai.com/index.htm')
except error.HTTPError as e:
print(e.reason, e.code, e.headers,sep='\n')
# URLErrorはHTTPErrorの親クラスなので、まず子クラスのエラーを捕捉し、その後親クラスのエラーを捕捉することができます
try:
response = request.urlopen('https://cuiqingcai.com/index.htm')
except error.HTTPError as e:
print(e.reason, e.code, e.headers, sep='\n')
except error.URLError as e:
print(e.reason)
else:
print('リクエスト成功')
# リンクを解析
# URLの標準インターフェースを処理し、URLの各部分の抽出、結合、リンク変換を実現します
# 1. urlparse
# urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
from urllib.parse import urlparse
result = urlparse('http://www.baidu.com/index.html;user?id=5#comment')
print(type(result),result)
# 標準リンク形式:scheme://netloc/path;params?query#fragment
<class 'urllib.parse.ParseResult'> ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5', fragment='comment')
# ParseResultは実際にはタプルで、インデックス順に取得することも、属性名で取得することもできます
result = urlparse('http://www.baidu.com/index.html#comment', allow_fragments=False)
print(result.scheme, result[0], result.netloc, result[1], sep='\n')
http
http
www.baidu.com
www.baidu.com
# 2. urlunparse
from urllib.parse import urlunparse
data = ['http', 'www.baidu.com', 'index.html', 'user', 'a=6', 'comment']
print(urlunparse(data))
http://www.baidu.com/index.html;user?a=6#comment
# 3. urlsplit
# urlparseメソッドと非常に似ており、params部分を個別に解析せず、5つの結果のみを返します。paramsはpathに統合されます
from urllib.parse import urlsplit
result = urlsplit('http://www.baidu.com/index.html;user?id=5#comment')
print(result)
SplitResult(scheme='http', netloc='www.baidu.com', path='/index.html;user', query='id=5', fragment='comment')
# 4. urlunsplit
from urllib.parse import urlunsplit
data = ['http', 'www.baidu.com', 'index.html', 'a=6', 'comment']
print(urlunsplit(data))
http://www.baidu.com/index.html?a=6#comment
# 5. urljoin
# urlunparseとurlunsplitはリンクの結合を完了できますが、特定の長さのオブジェクトが必要で、リンクの各部分を明確に分ける必要があります
from urllib.parse import urljoin
print(urljoin('http://www.baidu.com', 'FAQ.html'))
print(urljoin('http://www.baidu.com', 'https://cuiqingcai.com/FAQ.html'))
print(urljoin('http://www.baidu.com/about.html', 'https://cuiqingcai.com/FAQ.html'))
print(urljoin('http://www.baidu.com/about.html', 'https://cuiqingcai.com/FAQ.html?question=2'))
print(urljoin('http://www.baidu.com?wd=abc', 'https://cuiqingcai.com/index.php'))
print(urljoin('http://www.baidu.com', '?category=2#comment'))
print(urljoin('www.baidu.com', '?category=2#comment'))
print(urljoin('www.baidu.com#comment', '?category=2'))
http://www.baidu.com/FAQ.html
https://cuiqingcai.com/FAQ.html
https://cuiqingcai.com/FAQ.html
https://cuiqingcai.com/FAQ.html?question=2
https://cuiqingcai.com/index.php
http://www.baidu.com?category=2#comment
www.baidu.com?category=2#comment
www.baidu.com?category=2
# 6. urlencode: GETリクエストパラメータを構築
from urllib.parse import urlencode
params = {
'name':'germey',
'age':22
}
base_url = 'http://baidu.com?'
url = base_url + urlencode(params)
print(url)
http://baidu.com?name=germey&age=22
# 7. parse_qs 逆シリアル化、GETリクエストパラメータを辞書に戻す
from urllib.parse import parse_qs
query = 'name=germey&age=22'
print(parse_qs(query))
# 8. parse_qsl パラメータをタプルのリストに変換
from urllib.parse import parse_qsl
query = 'name=germey&age=22'
print(parse_qsl(query))
{'name': ['germey'], 'age': ['22']}
[('name', 'germey'), ('age', '22')]
# 9. quote: 中国語の文字をURLエンコーディングに変換
from urllib.parse import quote
keyword = ' 壁紙 '
url = 'https://www.baidu.com/s?wd=' + quote(keyword)
print(url)
# 10. unquote: URLデコードを行う
from urllib.parse import unquote
url = 'https://www.baidu.com/s?wd=%E5%A3%81%E7%BA%B8'
print(unquote(url))
https://www.baidu.com/s?wd=%20%E5%A3%81%E7%BA%B8%20
https://www.baidu.com/s?wd=壁紙
# Robotsプロトコルを分析
# robotparser
from urllib.robotparser import RobotFileParser
rp = RobotFileParser()
rp.set_url('http://www.jianshu.com/robots.txt')
rp.read()
print(rp.can_fetch('*', 'http://www.jianshu.com/p/b67554025d7d'))
print(rp.can_fetch('*', "http://www.jianshu.com/search?q=python&page=1&type=collections"))
False
False