質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

解決済

エンコードに関するエラーについて

S.katou
S.katou

総合スコア1

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

1回答

0評価

0クリップ

497閲覧

投稿2022/01/21 12:42

編集2022/01/22 15:46

pythonでguiを用いてスクレイピングツールを作っています

どうか助言をいただければ幸いです。
よろしくお願いいたします。

下のコードでスクレイピングすることは可能でしたが、3点問題がありまして
1.UnicodeEncodeError: 'latin-1' codec can't encode characters in position 8-13: ordinal not in range(256)という、エンコードに関するエラーが出てしまう
2.カウント機能が機能しておらず、記事数指定が出来ない及び、それらはVS Codeのデバッグ機能をすり抜けてしまう
3.VS Codeのpython上ではエラーが起きないが、パワーシェル(ターミナル)上で実行すると更に下のエラー文が出てきてしまう
という状況です。下図の通り、カウントが機能しないので送信上限の1000文字分だけ送っています。

イメージ説明
カウント機能を実装する時に出た以下エラーを無茶苦茶なint変換などで通したのが原因なのでしょうか?

python

if count > stop_count: TypeError: '>' not supported between instances of 'int' and 'str'

実際のコードです

python

#!/usr/bin/env python3 # -*- coding: UTF-8 -*- # # generated by wxGlade 1.1.0pre on Thu Jan 13 14:50:45 2022 # import wx from bs4 import BeautifulSoup import requests import datetime # begin wxGlade: dependencies # end wxGlade # begin wxGlade: extracode # end wxGlade class Myframe(wx.Frame): def __init__(self, *args, **kwds): # begin wxGlade: Myframe.__init__ kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) self.SetSize((800, 600)) self.SetTitle("記事スクレイピング") grid_sizer_1 = wx.GridSizer(4, 3, 0, 0) label_4 = wx.StaticText(self, wx.ID_ANY, "取得したいジャンル:") label_4.SetFont(wx.Font(15, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, 0, "")) grid_sizer_1.Add(label_4, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.ALL, 5) #コンボボックスの中身リストを作り、内部データとしてURLを埋め込む self.combo_box_3 = wx.ComboBox(self, wx.ID_ANY,"", style=wx.CB_DROPDOWN | wx.CB_READONLY) self.combo_box_3.Append("主要", 'https://news.yahoo.co.jp/topics/top-picks') self.combo_box_3.Append("国内", 'https://news.yahoo.co.jp/topics/domestic') self.combo_box_3.Append("国際", 'https://news.yahoo.co.jp/topics/world') self.combo_box_3.Append("経済", 'https://news.yahoo.co.jp/topics/business') self.combo_box_3.Append("エンタメ", 'https://news.yahoo.co.jp/topics/entertainment') self.combo_box_3.Append("スポーツ", 'https://news.yahoo.co.jp/topics/sports') self.combo_box_3.Append("IT", 'https://news.yahoo.co.jp/topics/it') self.combo_box_3.Append("科学", 'https://news.yahoo.co.jp/topics/science') self.combo_box_3.Append("ライフ", 'https://news.yahoo.co.jp/topics/life') self.combo_box_3.Append("地域", 'https://news.yahoo.co.jp/topics/local') self.combo_box_3.SetMinSize((200, 23)) self.combo_box_3.SetFont(wx.Font(9, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, 0, "Yu Gothic UI")) grid_sizer_1.Add(self.combo_box_3, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.ALL, 5) grid_sizer_1.Add((20, 20), 2, wx.ALIGN_CENTER | wx.ALL, 5) label_5 = wx.StaticText(self, wx.ID_ANY, "一度に取得したい記事数:") label_5.SetFont(wx.Font(15, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, 0, "")) grid_sizer_1.Add(label_5, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.ALL, 5) self.combo_box_4 = wx.ComboBox(self, wx.ID_ANY, "", style=wx.CB_DROPDOWN | wx.CB_READONLY) #str型を変換する方法が分からなかったので、愚直に内部データからかえてます self.combo_box_4.Append("1",1) self.combo_box_4.Append("2",2) self.combo_box_4.Append("3",3) self.combo_box_4.Append("4",4) self.combo_box_4.Append("5",5) self.combo_box_4.Append("6",6) self.combo_box_4.Append("7",7) self.combo_box_4.Append("8",8) self.combo_box_4.Append("9",9) self.combo_box_4.Append("10",10) self.combo_box_4.Append("11",11) self.combo_box_4.Append("12",12) self.combo_box_4.Append("13",13) self.combo_box_4.Append("14",14) self.combo_box_4.Append("15",15) self.combo_box_4.Append("16",16) self.combo_box_4.Append("17",17) self.combo_box_4.Append("18",18) self.combo_box_4.Append("19",19) self.combo_box_4.Append("20",20) self.combo_box_4.Append("21",21) self.combo_box_4.Append("22",22) self.combo_box_4.Append("23",23) self.combo_box_4.Append("24",24) self.combo_box_4.Append("25",25) self.combo_box_4.SetMinSize((200, 23)) grid_sizer_1.Add(self.combo_box_4, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.ALL, 5) grid_sizer_1.Add((20, 20), 2, wx.ALIGN_CENTER | wx.ALL, 5) grid_sizer_1.Add((20, 20), 2, wx.ALIGN_CENTER | wx.ALL, 5) self.button_5 = wx.Button(self, wx.ID_ANY, "実行") grid_sizer_1.Add(self.button_5, 2, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 5) self.button_6 = wx.Button(self, wx.ID_ANY, "キャンセル") grid_sizer_1.Add(self.button_6, 2, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5) self.SetSizer(grid_sizer_1) self.Layout() self.Bind(wx.EVT_BUTTON, self.OnExec, self.button_5) self.Bind(wx.EVT_BUTTON, self.OnCancel, self.button_6) # end wxGlade def OnExec(self, event): # wxGlade: MyFrame.<event_handler> global news,news2,news3,count try: url = self.combo_box_3.GetClientData(self.combo_box_3.GetSelection()) soup = BeautifulSoup(requests.get(url).text, 'lxml') d_today = datetime.date.today() news = "↓↓↓ 本日" + str(d_today) + "のニュース↓↓↓" + '\r\n' news2 = "ニュースの続き"'\r\n' # URL取得 news_urls = [] for li_tag in soup.find_all('li', {'class', 'newsFeed_item'}): try: news_urls.append(li_tag.find( 'a', {'class', 'newsFeed_item_link'})['href']) except: # 広告を読み飛ばす pass # 記事の題目と記事の発表日時 news_title = [] news_date = [] div_tags = soup.find_all('div', {'class', 'newsFeed_item_title'}) for div_tag in div_tags: news_title.append(div_tag.text) news_date.append(div_tag.next_sibling.find('time').text) #記事の取得数をカウントさせ、希望数に達した時点でブレイクする #1000文字の送信上限を考慮し、13記事まで取得した時点で次のメッセージで送信するようにしている count = 0 stop_count = 0 stop_count = self.combo_box_4.GetClientData(self.combo_box_4.GetSelection()) for title ,date ,url in zip(news_title, news_date, news_urls): if int(count) > int(stop_count): break elif count <= 13: news += '{} ({}) {}'.format(title, date, url) + '\r\n' else: news2 += '{} ({}) {}'.format(title, date, url) + '\r\n' count += 1 def send_line_notify(notification_message): #LINEに通知する line_notify_token = '(トークン名)yoBa589TcZI4cV' line_notify_api = 'https://notify-api.line.me/api/notify' headers = {'Authorization': f'Bearer {line_notify_token}'} data = {'message': f'message: {notification_message}'} requests.post(line_notify_api, headers = headers, data = data) def main(): #print(matome) send_line_notify(news) send_line_notify(news2) if __name__ == "__main__": main() except Exception as e: import traceback print(traceback.format_exc()) dlg = wx.MessageDialog(self, 'エラーが発生しました。入力内容を確認してください。', 'エラー', wx.OK | wx.ICON_ERROR ) dlg.ShowModal() dlg.Destroy() else: dlg = wx.MessageDialog(self, 'スクレイピング完了しました', '完了', wx.OK | wx.ICON_INFORMATION ) dlg.ShowModal() dlg.Destroy() def OnCancel(self, event): # wxGlade: Myframe.<event_handler> self.Destroy() # end of class Myframe class MyApp(wx.App): def OnInit(self): self.frame = Myframe(None, wx.ID_ANY, "") self.SetTopWindow(self.frame) self.frame.Show() return True # end of class MyApp if __name__ == "__main__": app = MyApp(0) app.MainLoop()

実行しましたところ、以下のエラー文が出てきました。
長大なエラー文ですが、エンコードに関するメッセージです。※同じ部分は省かせて頂きました。

python

Traceback (most recent call last): File "C:\Users\ユーザー名¥AppData\Local\Programs\Python\Python39\testcode2-2.py", line 142, in OnExec main() , line 138, in main send_line_notify(news) , line 134, in send_line_notify requests.post(line_notify_api, headers = headers, data = data) , line 117, in post return request('post', url, data=data, json=json, **kwargs) in request return session.request(method=method, url=url, **kwargs) line 542, in request resp = self.send(prep, **send_kwargs) line 655, in send r = adapter.send(request, **kwargs) line 439, in send resp = conn.urlopen( line 699, in urlopen httplib_response = self._make_request( line 394, in _make_request ", line 239, in request super(HTTPConnection, self).request(method, url, body=body, headers=headers) , line 1255, in request self._send_request(method, url, body, headers, encode_chunked) ", line 1296, in _send_request self.putheader(hdr, value) conn.request(method, url, **httplib_request_kw) , line 224, in putheader _HTTPConnection.putheader(self, header, *values) File "C:\Users\ユーザー名\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 1228, in putheader values[i] = one_value.encode('latin-1') UnicodeEncodeError: 'latin-1' codec can't encode characters in position 8-13: ordinal not in range(256)

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。