Yuki_in_OWL
@Yuki_in_OWL (Shinichi Sato)

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!

オンラインの補助金の情報を取得したい

解決したいこと

オンラインの補助金の情報を取得したい

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

UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-8-e3746e571df7> in <module>()
     66 
     67   req = urllib.request.Request(url, headers={'User-Agent': ua})
---> 68   hdata = urllib.request.urlopen(req)
     69   soup = BeautifulSoup(hdata, "html.parser")
     70 

9 frames
/usr/lib/python3.7/http/client.py in _encode_request(self, request)
   1208     #def _encode_request(self, request):
   1209         # ASCII also helps prevent CVE-2019-9740.
-> 1210         #return request.encode('ascii')
   1211 
   1212     def _validate_method(self, method):

UnicodeEncodeError: 'ascii' codec can't encode characters in position 37-38: ordinal not in range(128)

該当するソースコード

!apt-get update
!apt install chromium-chromedriver
!cp /usr/lib/chromium-browser/chromedriver /usr/bin
!pip install selenium

from selenium import webdriver
from time import sleep
from selenium.webdriver.common.keys import Keys
import requests
import csv
import datetime
from bs4 import BeautifulSoup

options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')

#キーワードを変えるとそれに合わせたCSVを出力します
keyword = "福祉"
url = 'https://api.jgrants-portal.go.jp/exp/v1/public/subsidies?keyword=' + keyword + '&sort=created_date&order=DESC&acceptance=1'
req = requests.get(url)

#新規CSVファイルの作成
csv_date = datetime.datetime.today().strftime("%Y%m%d")
csv_file_name = ( keyword + "jGrants" + csv_date + ".csv")
f = open(csv_file_name, "w", encoding="shift-jis", errors="ignore")#windowsの場合encoding=Shift-js

#requestによって得たデータ(文字列型)を配列、辞書型として読み込ませるためにeval関数を使用
#req.text = requestsで呼び出したデータをテキストに変更
l = eval(req.text)

#csvのヘッダー部分作成
writer = csv.writer(f, lineterminator="\n") 
csv_header = ["タイトル","ID","開始日","終了日","金額の上限","対象地域","対象となる従業員数","詳細","参照URL"]
writer.writerow(csv_header)

#req.textで得たデータのうち、result以下がリストになっているためfor文で分解
for i in l["result"]:
  id = i["id"]
 # name = i["name"]
  end = i["acceptance_end_datetime"]
  start = i["acceptance_start_datetime"]
  max = i["subsidy_max_limit"]
  title = i["title"]
  area = i["target_area_search"]
  number = i["target_number_of_employees"]

#上で分解したデータをcsvlistに格納し、csvに出力、ファイルを閉じる
  csvlist = []
  ID = []
  ID.append(id)
  csvlist.append(title)
  csvlist.append(id)
  csvlist.append(start)
  csvlist.append(end)
  csvlist.append(max)
  csvlist.append(area)
  csvlist.append(number)
 # csvlist.append(name)
#selenium,Chromedriverの定義
  wd = webdriver.Chrome('chromedriver',options=options)
#IDに格納したIDリストをもとにHPを開けてスクレイピング
  import urllib.request
  from bs4 import BeautifulSoup


  ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) '
  'AppleWebKit/537.36 (KHTML, like Gecko) '
  'Chrome/55.0.2883.95 Safari/537.36 '

  req = urllib.request.Request(url, headers={'User-Agent': ua})
  hdata = urllib.request.urlopen(req)
  soup = BeautifulSoup(hdata, "html.parser")

  import re
  for i in ID:
    refer = "https://www.jgrants-portal.go.jp/subsidy/" + i 
    wd.get(refer)
    sleep(3)
    detail = wd.find_element_by_tag_name("table").text
    print(detail)
    for j in range(0,detail.find('table')):
     j.decompose()
    print(detail)
  #  import re
  #  detail2 = re.findall("■目的・概要\s.*", detail)
    detail2=soup.find_all(text="■目的・概要")

    print(detail2)
    csvlist.append(detail2)
    csvlist.append(refer)
    writer.writerow(csvlist)

wd.close()

f.close()

自分で試したこと

ここに問題・エラーに対して試したことを記載してください。

0

1Answer

どうやら
req = urllib.request.Request(url, headers={'User-Agent': ua})という部分でのurlの中身に福祉という日本語が入っているため、エンコードエラーになっています。
試しに、福祉をutf8でエンコードした%E7%A6%8F%E7%A5%89%0Aをキーワードにしたところ、エラーは出ませんでした。

こちらの記事を参考にして、

.py
keyword = "福祉"
import urllib
keyword = urllib.parse.quote(keyword)

とすれば動きました。

1Like

Your answer might help someone💌