Python 3 Web Scraping'de 403 HTTP hatası


107

Alıştırma için bir web sitesini hurdaya çıkarmaya çalışıyordum, ancak 403 HTTP Hatası almaya devam ettim (benim bir bot olduğumu düşünüyor mu)?

İşte kodum:

#import requests
import urllib.request
from bs4 import BeautifulSoup
#from urllib import urlopen
import re

webpage = urllib.request.urlopen('http://www.cmegroup.com/trading/products/#sortField=oi&sortAsc=false&venues=3&page=1&cleared=1&group=1').read
findrows = re.compile('<tr class="- banding(?:On|Off)>(.*?)</tr>')
findlink = re.compile('<a href =">(.*)</a>')

row_array = re.findall(findrows, webpage)
links = re.finall(findlink, webpate)

print(len(row_array))

iterator = []

Aldığım hata:

 File "C:\Python33\lib\urllib\request.py", line 160, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Python33\lib\urllib\request.py", line 479, in open
    response = meth(req, response)
  File "C:\Python33\lib\urllib\request.py", line 591, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python33\lib\urllib\request.py", line 517, in error
    return self._call_chain(*args)
  File "C:\Python33\lib\urllib\request.py", line 451, in _call_chain
    result = func(*args)
  File "C:\Python33\lib\urllib\request.py", line 599, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden

Yanıtlar:


229

Bunun nedeni muhtemelen mod_securitybilinen örümcek / bot kullanıcı aracılarını engelleyen veya benzer bir sunucu güvenlik özelliğidir ( kolayca algılanabilir urllibgibi bir şey kullanır python urllib/3.3.0). Aşağıdakilerle bilinen bir tarayıcı kullanıcı aracısı ayarlamayı deneyin:

from urllib.request import Request, urlopen

req = Request('http://www.cmegroup.com/trading/products/#sortField=oi&sortAsc=false&venues=3&page=1&cleared=1&group=1', headers={'User-Agent': 'Mozilla/5.0'})
webpage = urlopen(req).read()

Bu benim için çalışıyor.

Bu arada, kodunuzda eksik ()sonra .readiçinde urlopençizgi, ama bir yazım hatası olduğunu düşünüyorum.

İPUCU: Bu bir egzersiz olduğundan, farklı, kısıtlayıcı olmayan bir site seçin. Belki bir urllibsebepten dolayı engelliyorlar ...


reqBirden fazla urlopenarama için yeniden kullanmanın güvenli olduğunu varsayıyorum .
Acumenus

1
Biraz geç olabilir, ancak Error 404: Access denied
kodumda

Bu işe yarıyor, ancak botları engellemek için iyi bir nedenleri olması gerektiğini düşünüyorum ve hizmet şartlarını ihlal ediyorum
xjcl

39

Kullanıcı aracısına bağlı olarak urllib kullanımınız nedeniyle kesinlikle engelliyor. Aynı şey bana OfferUp ile de oluyor. Kullanıcı aracısını Mozilla ile geçersiz kılan AppURLopener adında yeni bir sınıf oluşturabilirsiniz.

import urllib.request

class AppURLopener(urllib.request.FancyURLopener):
    version = "Mozilla/5.0"

opener = AppURLopener()
response = opener.open('http://httpbin.org/user-agent')

Kaynak


2
En iyi cevap benim için işe yaramadı, seninki ise. Çok teşekkürler!
Tarun Uday

Bu gayet iyi çalışıyor ancak buna ssl yapılandırmasını eklemem gerekiyor. Bunu nasıl yaparım? Onu ikinci bir parametre olarak eklemeden önce (urlopen (istek, bağlam = ctx))
Hauke

2
açılmış gibi görünüyor ama 'ValueError: kapalı dosyanın okunması' yazıyor
Martian2049

@zeta OfferUp'ı nasıl kazandınız ve aramayı bir komut dosyasından gerçekleştirmek için gerekli coğrafi koordinatları sağladınız?
CJ Travis

@CJTravis, OfferUp'ı almadım. Bir öğenin tam URL'sine göre öğe değerlerini alıyordum. Bu benim için herhangi bir coğrafi koordinat gerektirmedi
zeta

14

"Bunun nedeni muhtemelen mod_security veya bilinen bazı benzer sunucu güvenlik özellikleri

örümcek / bot

kullanıcı aracıları (urllib, python urllib / 3.3.0 gibi bir şey kullanır, kolayca algılanır) "- Stefano Sanfilippo tarafından daha önce belirtildiği gibi

from urllib.request import Request, urlopen
url="https://stackoverflow.com/search?q=html+error+403"
req = Request(url, headers={'User-Agent': 'Mozilla/5.0'})

web_byte = urlopen(req).read()

webpage = web_byte.decode('utf-8')

Web_byte sunucusu ve web sayfası içerik türü mevcut tarafından döndürülen bir bayt amacı, çoğunlukla UTF-8 . Bu nedenle, kod çözme yöntemini kullanarak web_byte'ın kodunu çözmeniz gerekir .

Bu, PyCharm kullanarak bir web sitesinden hurdaya çıkarmaya çalışırken problemin tamamını çözüyor

PS -> python 3.4 kullanıyorum


4

Önceki cevaba göre,

from urllib.request import Request, urlopen       
#specify url
url = 'https://xyz/xyz'
req = Request(url, headers={'User-Agent': 'XYZ/3.0'})
response = urlopen(req, timeout=20).read()

Bu, zaman aşımını uzatarak benim için çalıştı.


2

Sayfa, python programı içinde arama yaparken değil tarayıcıda çalıştığı için, url'ye hizmet eden web uygulamasının , içeriği tarayıcı tarafından değil, sizin talep ettiğinizi algıladığı anlaşılıyor.

Gösteri:

curl --dump-header r.txt http://www.cmegroup.com/trading/products/#sortField=oi&sortAsc=false&venues=3&page=1&cleared=1&group=1

...
<HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD><BODY>
<H1>Access Denied</H1>
You don't have permission to access ...
</HTML>

ve r.txt'deki içeriğin durum satırı vardır:

HTTP/1.1 403 Forbidden

Web istemcisini taklit eden 'Kullanıcı-Aracı' başlığını göndermeyi deneyin .

NOT: Sayfa, muhtemelen ayrıştırmak isteyeceğiniz tabloyu oluşturan Ajax çağrısını içerir. Tablonun içeriğini almak için hangi url'yi aramanız gerektiğini görmek için sayfanın javascript mantığını kontrol etmeniz veya sadece tarayıcı hata ayıklayıcıyı (Firebug / Net sekmesi gibi) kullanmanız gerekir.


2

Önceki cevaplara göre bu benim için Python 3.7 ile çalıştı

from urllib.request import Request, urlopen

req = Request('Url_Link', headers={'User-Agent': 'XYZ/3.0'})
webpage = urlopen(req, timeout=10).read()

print(webpage)

1

İki şekilde deneyebilirsiniz. Detay bu linkte .

1) pip ile

pip install - yükseltme sertifikası

2) Çalışmazsa , Mac için Python 3. * ile birlikte gelen bir Cerificates.command çalıştırmayı deneyin : (Python kurulum konumunuza gidin ve dosyayı çift tıklayın)

open / Applications / Python \ 3. * / Install \ Certificates.command


1

Kullanıcı aracısını Mozilla olarak taklit etmekten suçlu hissediyorsanız (Stefano'dan gelen en üstteki yanıtta yorum), urllib olmayan bir Kullanıcı Aracısı ile de çalışabilir. Bu, başvurduğum siteler için çalıştı:

    req = urlrequest.Request(link, headers={'User-Agent': 'XYZ/3.0'})
    urlrequest.urlopen(req, timeout=10).read()

Başvurum, makalelerimde bahsettiğim belirli bağlantıları kazıyarak geçerliliği test etmek. Genel bir kazıyıcı değil.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.