85815


GUI(wxpython)を用いてニュースサイトから記事をスクレイピングし、Lineへ送信するツールを作ろうとしております！

記事数をカウントするコードが上手くいってない状況です。  
送信上限の1,000文字を「news」へ一度に書き込んで、そこだけ送信してしまっているようです。[![画像の説明をここに入力](https://i.stack.imgur.com/0SkDh.png)](https://i.stack.imgur.com/0SkDh.png)  
こちらの最後のフィードバックとしまして  
count += 1のインデントがtry文上にあり、そこを間違えておりました。  
正しくは、for文と同じインデントにない為にカウントが機能しなかったようです。

[code]

    #Yahooニュースの記事は1ページで最大25件なので、それに合わせています
    #記事の取得数をカウントさせ、希望数に達した時点でブレイクする
            #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 count > stop_count:
                        break
                    elif count <= 13:
                        news += '{} ({}) {}'.format(title, date, url) + '\r\n'
                    else:
                        news2 += '{} ({}) {}'.format(title, date, url) + '\r\n'
    
                count += 1
    
[/code]

こちらが完成したコードとなります。

[code]

    #!/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, u"取得したいジャンル：")
            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(u"主要", 'https://news.yahoo.co.jp/topics/top-picks')
            self.combo_box_3.Append(u"国内", 'https://news.yahoo.co.jp/topics/domestic')
            self.combo_box_3.Append(u"国際", 'https://news.yahoo.co.jp/topics/world')
            self.combo_box_3.Append(u"経済", 'https://news.yahoo.co.jp/topics/business')
            self.combo_box_3.Append(u"エンタメ", 'https://news.yahoo.co.jp/topics/entertainment')
            self.combo_box_3.Append(u"スポーツ", 'https://news.yahoo.co.jp/topics/sports')
            self.combo_box_3.Append(u"IT", 'https://news.yahoo.co.jp/topics/it')
            self.combo_box_3.Append(u"科学", 'https://news.yahoo.co.jp/topics/science')
            self.combo_box_3.Append(u"ライフ", 'https://news.yahoo.co.jp/topics/life')
            self.combo_box_3.Append(u"地域", '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, u"一度に取得したい記事数：")
            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, u"実行")
            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, u"キャンセル")
            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,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文字の送信上限を考慮し、12記事まで取得した時点で次のメッセージで送信するようにしている
                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 count > stop_count:
                        break
                    elif count <= 12:
                        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 = '(トークン名)xGhyoBa589TcZI4cV'
                    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()
    
[/code]


CC BY-SA 4.0
2022-01-20T05:40:56.447
85811
2022-01-22T08:04:37.780
2022-01-22T08:04:37.780
50987
50987
question
python gui
pythonでGUIを用いて、ニュースサイトから記事をスクレイピングするツールを作ろうとしています


`self.combo_box_3.GetValue()`
とする場合は表示名(「主要」とか「国内」など)を取得します。なので、それを以下の様に書き換えます。

[code]

        def OnExec(self, event):  # wxGlade: MyFrame.<event_handler>
            global news,news2,news3
    
            try:
                self.combo_box_3.GetValue()
                self.combo_box_4.GetValue()
                # url = self.combo_box_3.GetValue()
                url = self.combo_box_3.GetClientData(self.combo_box_3.GetSelection())
    
[/code]

それから、`try ~ except` の範囲が長大で、かつ、エラー内容の表示が行われていませんので、`stacktrace`
を表示する様にしておく方がよろしいかと思います。

[code]

            except Exception as e:
                    import traceback
                    print(traceback.format_exc())
                    dlg = wx.MessageDialog(self, 'エラーが発生しました。入力内容を確認してください。',
                                        'エラー',
                                        wx.OK | wx.ICON_ERROR
                                        )
    
                               :
    
[/code]


CC BY-SA 4.0
2022-01-20T08:02:21.020
85815
2022-01-20T08:02:21.020
47127
85811
answer