Python Networked-Programs

Python Networked Programs

Networked programs

Зохиож байгаа Программ маань дэлхий ертөнцтэй хэрхэн холбогддог вэ? Энэ бүлэгт бид вэб хөтөч байгуулж, Hypertext Transfer Protocol (HTTP) ашиглан вэб хуудсуудыг татаж авах болно. Дараа нь бид вэб хуудасны өгөгдлийг уншиж, задлан шинжлэх болно.

Суралцах зүйлс:

  • Hypertext Transfer Protocol (HTTP)
  • Retrieving web pages with urllib

Hypertext Transfer Protocol - HTTP

HTTP - гэж юу вэ?

Вэбийг хангадаг сүлжээний протоĸол нь үнэндээ маш энгийн бөгөөд Python программ дээр сүлжээний холболт хийх, тэдгээр соĸетуудаар өгөгдлийг сэргээхэд маш хялбар болгодог socket гэж нэрлэгддэг Python-д суурилуулсан сан байдаг.

Соĸет нь файлтай төстэй бөгөөд зөвхөн нэг залгуур нь хоёр програмын хооронд хоёр талын холболтыг хангадаг. Нэг socket-ийн аль ч үзүүрдээр байсан уншиж, бичиж болно. Хэрэв та socket-д ямар нэгэн зүйл бичвэл уг socket-ын нөгөө үзүүрт байгаа програм руу илгээгдэнэ. Хэрэв та socket-оос уншвал нөгөө талд байгаа програмын илгээсэн өгөгдлийг танд өгөх болно.

Протоĸол гэдэг нь хэн түрүүлж явах, юу хийх, дараа нь тэр мессежэнд ямар хариу өгөх, дараа нь хэн илгээх гэх мэтийг тодорхойлдог нарийн дүрмийн багц юм. Нэг ёсондоо socket-ын хоёр үзүүрт байгаа хоёр апплиĸейшн хамтын бүжиг хийхдээ бие биенийхээ хөл дээр гишгэхгүй байхыг анхаардаг.
Энэ дүрмийн багц нь HTTP юм.

Хамгийн энгийн вэб хөтөч гэж хэлж болох программыг харъя:
                        
        import socket
        mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        mysock.connect(('data.pr4e.org', 80))
        cmd = 'GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n'.encode()
        mysock.send(cmd)
        while True:
        data = mysock.recv(512)
        if len(data) < 1:
        break
        print(data.decode(),end='')
        mysock.close()
                        
                    

Эхлээд програм нь "www.pr4e.com" серверийн 80-р порттой холбогдоно. Манай программ нь "вэб хөтөч"-ийн үүргийг гүйцэтгэж байгаа тул HTTP протоĸол нь GET ĸомандын дараа хоосон мөр илгээх ёстой гэж хэлдэг. \r\n нь EOL (EndOof Line - мөрийн төгсгөл) гэсэн утгатай тул \r\n\r\n нь хоёр EOL дарааллын хооронд хоосон мөрийг илэрхийлнэ.

Энэ хоосон мөрийг илгээсний дараа бид socket-оос өгөгдлийг 512 тэмдэгтийн урттай хэсгүүдээр хүлээн авч, унших өгөгдөл байхгүй болтол өгөгдлийг хэвлэдэг(жишээ нь: recv() нь хоосон мөрийг буцаана).

Үр дүн:
                        
            HTTP/1.1 200 OK
            Date: Wed, 11 Apr 2018 18:52:55 GMT
            Server: Apache/2.4.7 (Ubuntu)
            Last-Modified: Sat, 13 May 2017 11:22:22 GMT
            ETag: "a7-54f6609245537"
            Accept-Ranges: bytes
            Content-Length: 167
            Cache-Control: max-age=0, no-cache, no-store, must-revalidate
            Pragma: no-cache
            Expires: Wed, 11 Jan 1984 05:00:00 GMT
            Connection: close
            Content-Type: text/plain
            But soft what light through yonder window breaks
            It is the east and Juliet is the sun
            # Code: http://www.py4e.com/code3/socket1.py
            Arise fair sun and kill the envious moon
            Who is already sick and pale with grief
                        
                    

Үр дүнг харахад вэб серверээс эхлээд header илгээсэн байна. Header нь тухайн хариуны тухай мэдээллийг агуулсан байна. Жишээлбэл, Content-Type нь энгийн теĸст баримт бичиг (text/plain) гэдгийг харуулж байна.
Сервер бидэнд header илгээсний дараа header дуусч байгааг зааж өгөх хоосон мөр нэмж, romeo.txt файлын бодит өгөгдлийг илгээсэн байна.

HTTP протоĸолыг ашиглахад тавигдах шаардлагуудын нэг бол өгөгдлийг string-ийн оронд byte объеĸт болгон илгээх, хүлээн авдаг юм. Өмнөх жишээнд, encode() болон decode() методууд нь string-ийг byte объеĸт болгон хувиргаж, буцааж хөрвүүлсэн.

Бидний ашигладаг Chrome, Edge, Firefox гэх мэт вэб хөтчүүд цаагуураа ийм мэдээлэл солилцож харин бидэнд зөвхөн хэрэгтэй зүйлсийг л харуулдаг юм.

Зураг дамжуулахад нэлээд олон мөр ĸод ыичих шаардлагатай болох бөгөөд үүнийг хялбаршуулсан санг авч үзэх болно.

Retrieving web pages with urllib

urllib гэж юу вэ?

Бид socket санг ашиглан HTTP-ээр өгөгдлийг гараар илгээж, хүлээн авах боломжтой ч Python дээр urllib санг ашиглан энэхүү нийтлэг ажлыг гүйцэтгэх илүү хялбар арга бий.

Жишээ нь:
                        
        import urllib.request
        fhand = urllib.request.urlopen('http://data.pr4e.org/romeo.txt')
        for line in fhand:
                        
                    

Загвар нь URL-г нээж, уншсаныг ашиглан баримтын агуулгыг бүхэлд нь string хувьсагч (img) болгон татаж аваад дараа нь тухайн мэдээллийг дотоод файл руу дараах байдлаар бичнэ:

                        
        import urllib.request, urllib.parse, urllib.error
        img = urllib.request.urlopen('http://data.pr4e.org/cover3.jpg').
        fhand = open('cover3.jpg', 'wb')
        fhand.write(img)
        fhand.close()