/ Python / 👁 2626 Okunma

Python Site Çekme İşlemi | Detaylı Anlatım

Python ile istediğiniz bir siteyi çekmek ve analiz etmek, siteyi çekerken GET, POST, HEADERS ve DATA gibi parametreler göndermek gibi ihtiyaçlarınız varsa yazımıza hoşgeldiniz diyoruz. Bu konuda Python ile en iyi site çekme işleminin nasıl yapıldığını öğreneceksiniz.

Bildiğiniz gibi tarayıcılar nasıl ki web sayfalarına istek gönderip sonuç döndürüyorsa, bizlerde arada tarayıcılar olmadan sadece belirli protokolleri kullanarak istediğimiz sayfalara request (istek) gönderip response (sonuç) alabiliriz. Tabi işleme tabi olacak sayfanın bizden istediği gereklilikleri öncelikle analiz etmeliyiz. Bu sayede hiçbir engele takılmadan başarılı bir şekilde internet sayfalarını çekebiliriz. Öyleyse başlayalım.

Kütüphanelerimizi Dahil Edelim

Python ile site çekmek ve ardından sayfayı analiz etmek için iki kütüphaneye ihtiyaç duyuyoruz. Bunlar requests ve BeautifulSoup kütüphaneleridir. Öyleyse ne işe yaradıklarını anlatmakla başlayalım.

Requests, çok basit bir şekilde HTTP/1.1 istekleri göndermenize imkan verir. Üstelik bunu yaparken GET, POST, PUT, DELETE, HEAD, OPTIONS gibi istek türlerini rahatça kullanabilirsiniz. Sonuç olarak ise HTTP isteğinizin döngüsünü olduğu gibi size yansıtır. Ayrıca isteklerinizi yaparken parametleri url sonuna yazmaya gerek yoktur. Birazdan göstereceğim birçok kolaylık Requestin özünde vardır. Kütüphaneyi şu komutla indirebilirsiniz.

git clone git://github.com/requests/requests.git
cd requests
pip install

BeautifulSoup ise Requests ile dönen içeriği parse etmenizi, yani dilimleyerek içinden istdeğiniz bölümleri almanızı sağlar. Üstelik HTML, XML, JSON gibi döndü sonuçları ile rahatlıkla işlemler yapabilirsiniz. Zaten birçok örneğini aşağıda göstereceğiz. Kütüphaneyi şu komutla indirebilirsiniz:

pip install beautifulsoup4

Requests İle Sayfaları Farklı Metodlarla Çekelim

Artık birkaç siteyi farklı HTTP methodları ile çekmeye başlayalım. Öncelikle GET kullanalım ve sayfamızı çekelim.

from bs4 import BeautifulSoup
import requests
 
url = "https://www.w3schools.com/php/demo_intro.php"
 
istek = requests.get(url)
html = istek.content
 
print(html)

Şimdi ekrana yazdırdığımız sonuca bakalım:

b'<!DOCTYPE html>\r\n<html>\r\n<body>\r\n\r\nMy first PHP script! \r\n\r\n</body>\r\n</html>'

Gördüğünüzü gibi content ile istekte bulunduğumuz sayfanın html kodlarına sayfada yer alan tüm karakter şemasıyla ulaştık. Bir de bu formatı daha düzgün bir HTML formatında isteyelim.

from bs4 import BeautifulSoup
import requests
 
url = "https://www.w3schools.com/php/demo_intro.php"

istek = requests.get(url)
html = istek.text
 
print(html)

Şimdi ekrana yazdırdığımız sonuca bakalım:

<!DOCTYPE html>
<html>
<body>
 
My first PHP script!
 
</body>
</html>

Gördüğünüz gibi artık sonuçlarımız daha düzgün bir formatta. Şimdi ise isteğimize dönen durum kodunu, gönderdiğimiz urli, sonucu json olarak yazdırmayı öğrenelim ama istek = requests.get(url) e kadar olan bölüm aynı olduğu için sadece geri kalanları yazacağım.

Durum kodunu çekelim

html = istek.status_code
print(html)

Sonuç:

200

Raw formatında çekelim

istek = requests.get(url, stream=True)
html = istek.raw
print(html)
print(html.read(10))

Sonuç:

<urllib3.response.HTTPResponse object at 0x000002408BC02668>
b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x04\x00'

JSON içeriğini çekelim

url = "https://api.github.com/events"

istek = requests.get(url)
html = istek.json()

Sonuç:

{'message': 'Not Found', 'documentation_url': 'https://developer.github.com/v3'}

!!!! Eğer çekmeye çalıştığınız sayfa json formatında değilse hata alırsınız.

Şimdi ise küçük bir POST örneği yapalım ve ardından diğer aşamaya geçelim.

from bs4 import BeautifulSoup
import requests
 
url = "https://www.w3schools.com/php/demo_intro.php"

istek = requests.post(url)
html = istek.text
 
print(html)

Şimdi ekrana yazdırdığımız sonuca bakalım:

<!DOCTYPE html>
<html>
<body>
 
My first PHP script!
 
</body>
</html>

Gördüğünüz gibi hiçbir farkı yok. POST un ayrıcalığı bize istekte bulunduğumuz sayfalara parametre gönderme, header ayarlama gibi işlemlerde sağladığı kolaylıkla anlaşılır. Hemen deneyelim:

url = "http://httpbin.org/post"
parametreler = {'key1': 'value1', 'key2': 'value2'}

istek = requests.post(url, data=parametreler)

print(istek.text)

Ne çekmiş bakalım

{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "key1": "value1",
    "key2": "value2"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "close",
    "Content-Length": "23",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.18.4"
  },
  "json": null,
  "origin": "213.14.10.58",
  "url": "http://httpbin.org/post"
}

Gördüğünüz gibi gönderdiğimiz parametreler nede güzel ulaşmış yerine :)

Aynı şekilde header de ayarlayabiliriz:

url = "https://www.w3schools.com/php/demo_intro.php"
baslik = {'user-agent': 'my-app/0.0.1'}

istek = requests.post(url, headers=baslik)

Böylelikle istek yaptığınız sayfalara özel header başlıklarıyla gidebilirsiniz.

Request için daha detaylı dökümana ulaşmak isterseniz Tıklayınız.

BeutifulSoup İle Çektiğimiz Sayfaları İşleyelim

Yukarıda web sayfalarını Python ile nasıl çekebileceğimizi gördünüz. Birkaç pratikten sonra rahatlıkla oturacaktır çünkü olabildiğince basit bir formata sokulmuş halde (Requests sayesinde). Şimdi ise dönen sonuçları nasıl işleyeceğimizi, belirli etiketleri nasıl işleyebileceğimizi gösterelim.

Öncelikle çektiğimiz bir sayfayı soup değişkinine BeautifulSoup sayesinde atayacağız ve ardından sayfanın titlesini çekeceğiz.

from bs4 import BeautifulSoup
import requests

url = "https://kerteriz.net"

istek = requests.get(url = url)
html = istek.text
soup = BeautifulSoup(html, 'html.parser')

print(soup.title)
print(soup.title.text)

Sonuca bakalım (sadece title ve html ile beraber)

<title>Kerteriz</title>
Kerteriz

Şimdi sadece belirli etiketleri çekelim.

print(soup.a)
print(soup.meta)
print(soup.li)

Sonuca bakalım (bu kullanım şekli belirtilen etiketin sadece ilk elemanını çeker. Yani 10 tane a etiketiniz varsa sadece ilk a etiketini size gösteri)==

<a href="https://kerteriz.net/">ANA SAYFA</a>
<meta charset="utf-8"/>
<li class="nav-ana-sayfa nav-current" role="menuitem">

Peki tüm li etiketlerimizi çekmek istersek ne yapacağız?

print(soup.find_all('li'))

Sonuca bakalım

[<li class="nav-ana-sayfa nav-current" role="menuitem"><a href="https://kerteriz.net/">ANA SAYFA</a></li>, <li class="nav-ghost-trkiye" role="menuitem"><a href="https://kerteriz.net/tag/ghost-tr/">GHOST TÜRKİYE</a></li>, <li class="nav-python" role="menuitem"><a href="https://kerteriz.net/tag/python/">PYTHON</a></li>, <li class="nav-indirmelik" role="menuitem"><a href="https://kerteriz.net/tag/indirmelik/">İNDİRMELİK</a></li>]

Son olarak ise belirli bir class veya id ye sahip etiketleri nasıl çekeceğimizi gösterelim

for i in soup.find_all("div",{"class":"view-container"}):
    print(i)

Şimdi biz ne yaptık? Tüm site içeriğinden view-container classına sahip div leri çektik ve listeledik.

[<li class="nav-ana-sayfa nav-current" role="menuitem"><a href="https://kerteriz.net/">ANA SAYFA</a></li>, <li class="nav-ghost-trkiye" role="menuitem"><a href="https://kerteriz.net/tag/ghost-tr/">GHOST TÜRKİYE</a></li>, <li class="nav-python" role="menuitem"><a href="https://kerteriz.net/tag/python/">PYTHON</a></li>, <li class="nav-indirmelik" role="menuitem"><a href="https://kerteriz.net/tag/indirmelik/">İNDİRMELİK</a></li>]

Ve daha birçok kullanım şekline ve gerekli dökümana ulaşmak için Tıklayınız

SONUÇ

Yukarıdaki örneklerde gördüğünüz üzere farklı methodlarla sayfalarımızı çektik ve dönen içerik üzerinde arama ve listeleme işlemleri gerçekleştirdik. Tabi bunlar küçük bir özet sayılır çünkü daha o kadar çok farklı yöntem var ki bir yazıda anlatmak çok zor olurdu. Bu yüzden verdiğim linkler üzerinden Requests ve BeautifulSoup kütüphanelerinin dökümanlarını inceleyebilirsiniz.

Aklınıza takılan sorular için aşağıya yorum bırakmayı da unutmayınız. Umarım bundan sonra Python ile istediğiniz sayfaları rahatça çekebilirsiniz. Hepinize iyi günler dilerim.