Python 3 WebスクレイピングのHTTPエラー403


100

私は練習のためにWebサイトをスクラップにしようとしましたが、HTTPエラー403を受け取り続けました(ボットだと思いますか?)

これが私のコードです:

#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 = []

私が得るエラーは:

 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

回答:


206

これはおそらく、mod_security既知のスパイダー/ボットユーザーエージェントをブロックする同様のサーバーセキュリティ機能(のurllibようなものを使用しpython urllib/3.3.0、簡単に検出されます)が原因です。既知のブラウザのユーザーエージェントを次のように設定してみてください。

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()

これでうまくいきます。

ちなみに、あなたのコードではあなたは行の()後ろ.readを逃していますがurlopen、それはタイプミスだと思います。

ヒント:これは練習なので、別の制限のないサイトを選択してください。多分彼らはurllib何らかの理由でブロックしています...


req複数のurlopen呼び出しで再利用しても安全だと思います。
アキュメナス

少し遅れるかもしれませんが、コードにUser-Agentがすでにありますが、それでも私に与えられますError 404: Access denied
Reema Parakh

これは機能しますが、ボットをブロックする十分な理由があるはずだと思います。ボットは利用規約に違反しています
xjcl

39

ユーザーエージェントに基づいてurllibを使用しているため、間違いなくブロックされています。これと同じことが、OfferUpでも起こっています。ユーザーエージェントをMozillaでオーバーライドするAppURLopenerという新しいクラスを作成できます。

import urllib.request

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

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

ソース


2
一番上の答えはうまくいきませんでした。どうもありがとう!
Tarun Uday 2016年

これは問題なく動作しますが、これにssl構成をアタッチする必要があります。どうすればよいですか?2つ目のパラメーター(urlopen(request、context = ctx))として追加する前に
Hauke

2
開いたように見えますが、「ValueError:閉じたファイルの読み取り」と表示されます
Martian2049

@zetaスクリプトから検索を実行するために、どのようにしてOfferUpをスクレイピングし、必要な地理座標を提供しましたか?
CJ Travis 2017年

@CJTravis、私はOfferUpをかき集めていませんでした。ちょうどアイテムの正確なURLに基​​づいてアイテムの値を取得していました。それには、地理座標は必要ありませんでした
ゼータ

13

「これは、おそらくmod_securityまたは既知のサーバーをブロックする類似のサーバーセキュリティ機能が原因です。

クモ/ボット

ユーザーエージェント(urllibはpython urllib / 3.3.0のようなものを使用し、簡単に検出されます) "-Stefano Sanfilippoによってすでに言及されています

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は、サーバーとWebページのコンテンツタイプの存在によって返されたバイトのオブジェクトであるほとんどであるUTF-8 。したがって、decode メソッドを使用してweb_byteをデコードする必要があります。

これは、PyCharmを使用してWebサイトからスクラップを作成しようとしていたときの完全な問題を解決します

PS->私はpython 3.4を使用しています


1

ページはブラウザーで機能し、Pythonプログラム内で呼び出すときは機能しないため、そのURLを提供するWebアプリは、ブラウザーではなくコンテンツを要求したことを認識しているようです。

デモンストレーション:

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>

r.txtのコンテンツにはステータス行があります:

HTTP/1.1 403 Forbidden

ウェブクライアントを装ったヘッダー「User-Agent」を投稿してみてください。

注:このページには、おそらく解析したいテーブルを作成するAjax呼び出しが含まれています。ページのJavaScriptロジックを確認するか、ブラウザデバッガ(Firebug / Netタブなど)を使用して、テーブルのコンテンツを取得するために呼び出す必要があるURLを確認する必要があります。


1

2つの方法で試すことができます。詳細はこのリンクにあります。

1)ピップ経由

pip install --certifiのアップグレード

2)機能しない場合は、Python 3. * for MacにバンドルされているCerificates.commandを実行しててください(Pythonのインストール場所に移動し、ファイルをダブルクリックします)。

/ Applications / Python \ 3。* / Install \ Certificates.commandを開きます


1

以前の答えに基づいて、

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()

これは、タイムアウトを延長することでうまくいきました。


0

ユーザーエージェントをMozillaとして偽装することに罪悪感がある場合(Stefanoからのトップアンサーのコメント)、urllib以外のユーザーエージェントでも動作する可能性があります。これは私が参照するサイトで機能しました:

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

私のアプリケーションは、私の記事で参照している特定のリンクをスクレイピングして妥当性をテストすることです。一般的なスクレーパーではありません。


0

以前の回答に基づいて、これはPython 3.7で私のために機能しました

from urllib.request import Request, urlopen

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

print(webpage)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.