@takapiro926

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

PythonでのWebスクレイピングで403 Forbiddenが出た場合

解決したいこと

PythonでWebデータをダウンロードしているのですが、エラーメッセージ「403 Forbidden」と表示され、ダウンロードできなくなってしまいました。

Qiitaや他Webサイトで、headerを変更すれば可能、と読み、対応してみたのですが、これでもうまくいきません。
インドネシア証券取引所から上場企業の決算データ(XBRL)をDLしてくる、というニッチなことをやっているのですが、おそらく同証券取引所Webサイトが、何らかの更新を行ったことによるのではと思っています。
初心者なりに色々な本を読んで作成したコードなので、あまりきれいなものではないのですが、
2か月前まではきちんとDLできており、ソースコードや動作環境による問題ではないように思います。
(念の為、コードの主要部分を全部記載しておきます)

発生している問題・エラー

403 Forbidden

該当するソースコード

ticker = input()
fy = input()
period = ()

def download_file(url):
    """Direct URL and DL file"""
    filename = url.split('/')[-1]
    r = requests.get(url, stream=True)
    with open(filename, 'wb') as f:
        for chunk in r.iter_content(chunk_size=1024):
            if chunk:
                f.write(chunk)
                f.flush()
        return filename
    # error statement if cannot open file
    return False

def zip_extract(filename):
    """open zip file"""
    target_directory = "."
    zfile = zipfile.ZipFile(filename)
    zfile.extractall(target_directory)

url ='https://www.idx.co.id/Portals/0/StaticData/ListedCompanies/Corporate_Actions/New_Info_JSX/Jenis_Informasi/01_Laporan_Keuangan/02_Soft_Copy_Laporan_Keuangan//Laporan%20Keuangan%20Tahun%20'+str(fy)+'/'+period+'/'+ticker+'/'+'instance.zip'

hds = {'User-Agent': "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0"}
try:
   req = urllib.request.Request(url, headers=hds)
   urllib.request.urlopen(req)
   co_dir = 'data/'+ticker
   new_dir_path = ticker+str(fy)+period
   if not os.path.exists(co_dir):
       os.makedirs(co_dir)
   os.chdir(co_dir)
   if not os.path.exists(new_dir_path):
       os.makedirs(new_dir_path)
   os.chdir(new_dir_path)
   target_directory = new_dir_path+'/'

   if __name__ == "__main__":
       filename = download_file(url)
       if filename:
          print(ticker+str(fy)+period+'is downloaded.'.format(filename))
          filename = 'instance.zip'
          zip_extract(filename)
       else:
          print(ticker+fy+period+'download is failed.'.format(filename))

自分で試したこと

上記hdsを追加したのですが、やはりDLできませんでした。

Web上で解決方法を探したのですが、他には見つからず、ここで質問するものです。
対象のWebサイトのここを見ればわかる、といったアドバイスでもよいので、何かとっかかりを
頂ければ幸いです。

0 likes

1Answer

WEBサーバーでブラウザ以外からのアクセスは403を返すような設定が可能ですので、スクレイピングを許可していないサーバーでは設定されていることがあります。
User-Agentで回避できない場合、どのように検知してるのかわからない限り回避は難しいと思います。

0Like

Your answer might help someone💌