16 เมษายน 2558

Published 4/16/2558 by with 0 comment

urllib เข้าถึงอินเทอร์เน็ตใน Python 3

ในภาษา Python เราสามารถเขียนโปรแกรมเพื่อเข้าถึงข้อมูลบนโลกอินเทอร์เน็ตได้ด้วยไลบรารีพื้นฐานของ Python ที่มีชื่อว่า urllib
เนื้อหาบทความนี้ใช้ได้เฉพาะ Python 3 ครับ

โดยไลบรารี urllib นี้สามารถเข้าถึงข้อมูลและดึงข้อมูลได้ไม่ว่าจะเป็น GET และ POST โดยไลบรารี urllib ประกอบไปด้วยไลบรารีย่อย ๆ ดังนี้ :

  • urllib.request สำหรับใช้เปิดลิงค์และ request

  • urllib.error สำหรับใช้แสดงความผิดพลาดของ urllib.request เพื่อให้ดำเนินการตามที่ต้องการ

  • urllib.parse สำหรับใช้ทำ parsing URL

  • urllib.robotparser สำหรับใช้ parsing ไฟล์ robots.txt files


เนื่องจากรายลเอียดปลีกย่อยการใช้งานไลบรารี urllib มีคำสั่งจำนวนมาก ผมจึงขอนำเสนอเสนอฟังก์ชันคำสั่งที่ใช้งานบ่อยเท่านั้นครับ




urllib.request

เป็นไลบรารีสำหรับเรียกใช้ HTTP/1.1 และ Connection:close header ใน HTTP requests

คำสั่ง

[python]urllib.request.urlopen(url, data=None, [timeout, ]*)[/python]

เป็นคำสั่งสำหรับเปิดลิงค์ที่เรากำหนด

  • url เป็นลิงค์ของหน้าเพจที่ต้องการ

  • data เป็นข้อมูลชนิดของ requests แต่ปัจจุบันเราใช้ Http เป็น requests เลยไม่ต้องจำเป็นต้องกำหนดก็ได้

  • timeout เวลาหมดการรอข้อมูล


ตัวอย่างการใช้งาน

[python]
>>> import urllib.request
>>> f = urllib.request.urlopen('http://www.python.org/')
>>> print(f.read(300)) #อ่านข้อมูลแค่ 300 ไบต์
b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n\n<html
xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n\n<head>\n
<meta http-equiv="content-type" content="text/html; charset=utf-8" />\n
<title>Python Programming '
[/python]

แต่ตัวอย่างด้านบนอาจมีปัญหาเรื่อง encoding หาก encoding ไม่ใช่ UTF-8 ดังนั้นเราจึงควรกำหนดการ encoding ข้อมูลไว้เพื่อทำการ decode ด้วยครับ

[python]
>>> import urllib.request
>>> f = urllib.request.urlopen('http://www.python.org/')
>>> print(f.read(100).decode('utf-8'))
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtm
[/python]

คำสั่งต่อมา

[python]urllib.request.Request(url)[/python]

เป็นคำสั่งสำหรับ request ข้อมูล
ตัวอย่างเช่น
เราทำไฟล์ test.cgi โดยมีที่อยู่ที่ https://localhost/cgi-bin/test.cgi โดยมีโค้ดดังนี้

[python]
#!/usr/bin/env python
import sys
data = sys.stdin.read()
print('Content-type: text-plain\n\nGot Data: "%s"' % data)
[/python]

เมื่อรัน CGI แล้วลองเขียนโปรแกมโดยใช้คำสั่ง urllib.request.Request() แล้วลองรัน

[python]
>>> import urllib.request
>>> req = urllib.request.Request(url='https://localhost/cgi-bin/test.cgi',
... data=b'This data is passed to stdin of the CGI')
>>> f = urllib.request.urlopen(req)
>>> print(f.read().decode('utf-8'))
Got Data: "This data is passed to stdin of the CGI"
[/python]

จะเห็นได้ว่า โปรแกรมได้ทำการส่งข้อมูล request ไปยังเซิฟเวอร์ครับ

คำสั่ง

[python]urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)[/python]

เป็นคำสั่งสำหรับใช้คัดลอกวัตถุจากเครือข่ายครับ เราสามารถใช้คำสั่งนี้โหลดไฟล์จากอินเทอร์ได้ครับ
โดยสามารถใช้งานได้ดังนี้ครับ

[python]
import urllib.request
urllib.request.urlretrieve(ลิงค์, ชื่อไฟล์ที่บันทึก)
[/python]

ตัวอย่างเช่น

[python]
import urllib.request
urllib.request.urlretrieve('https://python3.wannaphong.com/wp-content/plugins/wp-socializer/public/social-icons/wp-socializer-sprite-mask-32px.gif', 'RSS.gif')
[/python]

จะเห็นได้ว่า มีไฟล์ RSS.gif ในโฟลเลอร์ของไฟล์ python ที่รันครับ

เปลี่ยน Headers

ในบางเว็บได้มีบล็อกการเข้าถึงจาก Headers ที่ไม่รู้จัก เราจึงต้องปลอม Headers ครับ

[python]
import urllib.request
url = 'http://user-agent.me'

headers = {}
headers['User-Agent'] = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36 OPR/28.0.1750.51"
req = urllib.request.Request(url, headers = headers)
resp = urllib.request.urlopen(req)
Data = resp.read()
print(Data)
[/python]





urllib.parse

เป็นไลบรารีสำหรับทำการ parse ลิงค์โดยเฉพาะครับ

คำสังที่ใช้บ่อยคือ
คำสั่ง

[python]urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)[/python]

ตัวอย่างการใช้งาน

[python]
>>>> from urllib.parse import urlparse
>>>> url = urlparse("https://www.google.com/") #ทำการ parse ลิงค์
>>>> url
ParseResult(scheme='https', netloc='www.google.com', path='/', params='', query=
'', fragment='')
>>>> scheme = url.scheme
>>>> loc = url.netloc
>>>> path = url.path
>>>> print(scheme)
https
>>>> print(loc)
www.google.com
>>>> print(path)
/
[/python]

คำสั่ง

[python]urllib.parse.urljoin(base, url, allow_fragments=True)[/python]

เป็นคำสั่งสำหรับเติมลิงค์เข้าไปกับ base URL ครับ
ตัวอย่างเช่น

[python]
>>> from urllib.parse import urljoin
>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
'http://www.cwi.nl/%7Eguido/FAQ.html'
[/python]

คำสั่ง

[python]urllib.parse.SplitResult.geturl()[/python]

บางครั้งลิงค์ที่ส่งมาเป็นตัวพิมพ์ใหญ่ทำให้เวลาเรียกใช้งาน ไม่สามารถทำงานได้ คำสั่งนี้เป็นคำสั่งสำหรับเรียกคืนลิงค์ต้นฉบับครับ
ตัวอย่างเช่น

[python]
>>> from urllib.parse import urlsplit
>>> url = 'HTTP://www.Python.org/doc/#'
>>> r1 = urlsplit(url)
>>> r1.geturl()
'http://www.Python.org/doc/'
>>> r2 = urlsplit(r1.geturl())
>>> r2.geturl()
'http://www.Python.org/doc/'
[/python]





urllib.error
เป็นไลบรารีสำหรับใช่แสดงข้อผิดพลาดในการเรียกใช้งานข้อมูลจากลิงค์ครับ โดยต้องใช้คู่กับ exception เท่านั้นครับ
คำสั่ง

[python]
urllib.error.URLError
[/python]

ตัวอย่างเช่น

[python]
>>> import urllib.request
>>> req = urllib.request.Request('http://www.python.org/fish.html')
>>> try:
... urllib.request.urlopen(req)
... except urllib.error.HTTPError as e:
... print(e.code)
... print(e.read())
...
404
b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n\n<html
...
<title>Page Not Found</title>\n
...
[/python]





urllib.robotparser

เป็นไลบรารีสำหรับใช้ parsing ไฟล์ robots.txt files
คำสั่งในไลบรารีนี้มีแค่

[python]urllib.robotparser.RobotFileParser(url='')[/python]

ตัวอย่างการใช้งาน

[python]
>>> import urllib.robotparser
>>> rp = urllib.robotparser.RobotFileParser()
>>> rp.set_url("http://www.musi-cal.com/robots.txt")
>>> rp.read()
>>> rp.can_fetch("*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco")
False
>>> rp.can_fetch("*", "http://www.musi-cal.com/")
True
[/python]





อ่านรายละเอียดไลบรารี urllib เพิ่มเติมได้ที่ https://docs.python.org/3/library/urllib.html

ติดตามบทความต่อไปนะครับ

ขอบคุณครับ

0 ความคิดเห็น:

แสดงความคิดเห็น

แสดงความคิดเห็นได้ครับ :)