从使用请求获取数据和beautifulsoup4

时间:2018-05-28 14:04:15

标签: python-3.x beautifulsoup python-requests

为了更好地学习beautifulsoup4,我试图从https://semlar.com/rivenprices/artax获取一些数据(我当然会将这些数据仅用于学习目的,以避免任何潜在的法律问题。所有我在这里发布的数据可供所有使用“检查”浏览器功能的人使用。

此网站显示了名为Warframe的游戏中特殊模组的平均价格,但除此之外。我想编写一个应用程序,它从用户那里获取mod名称(例如Artax,Lanka等)并打印“Avg Price”和“Dispo”值。

这是指向我想要获取数据的表的一小部分的链接: https://imggmi.com/full/2018/5/28/daa550ff5f042bb80ab0ecdd980a3935-full.png.html

之前我做了这样的应用程序,但在这里我遇到了一个问题 - 武器,价格和'处置'的名称似乎隐藏在tbody标签下,当我用数据搜索数据时它是空的bs4

我的计划到目前为止:

import requests
import bs4

url = requests.get('https://semlar.com/rivenprices/artax').text
soup = bs4.BeautifulSoup(url, 'html.parser')
data = soup.find(class_='table')

在这种情况下,data是:

<table class="table" id="riven-table">
<thead>
<tr>
<th>Riven Name</th>
<th class="price-avg">Avg Price</th>
<th class="riven-disposition">Dispo</th>
</tr>
</thead>
<tbody>
</tbody>
</table>

如您所见,<tbody>标记为空,但当您检查浏览器中表格中的任何元素时,它似乎只是在<tbody><tr><td>下的此标记内 - 这是截图显示部分检查代码:

https://imggmi.com/full/2018/5/28/0619e4d1944c0291bfa70a30678b3f51-full.png.html

1 个答案:

答案 0 :(得分:0)

你知道他们说了什么:如果他们把你扔出门,请从窗户回来。

我设法以非常不同的方式做我想要的事情,我称之为“暴力 - 非安全和可靠的”方式。该计划:

  1. 打开网页浏览器,等待固定时间直到网页加载,自动按 Ctrl + A ,再等一会儿,按 Ctrl + C 并关闭浏览器(或浏览器卡,如果有很多)。在这里,我使用了webbrowsertimepywinauto模块。
  2. 将剪贴板粘贴到rawdata.txt文件。我这样做只是为了确保我不会弄乱我的测试,而我通过随机复制一些文本来反复编写和运行代码。我用pyperclip来做这件事。稍后打开该文件并格式化内容以创建{'weapon_name': ['mod_price', 'disposition'], 'next_weapon_name: [...], ...}形式的字典。
  3. 最后,程序询问用户他想要检查的武器名称,并向他提供词典中的数据。然后他可以再次重新运行循环来询问其他枪或者只是结束程序。
  4. 代码:

    from time import sleep
    import webbrowser
    import pywinauto.keyboard as pkbd
    import pyperclip
    
    url = 'https://semlar.com/rivenprices/lanka'
    
    
    def greet():
        print("This app will get data from {}".format(url))
        print("You will be able to check riven mod price and disposition for desired weapon.")
    
    
    def open_browser_get_to_clipboard():
        webbrowser.open(url)
        sleep(10)
        pkbd.SendKeys('^a')
        sleep(2)
        pkbd.SendKeys('^c')
        sleep(1)
        pkbd.SendKeys('%{F4}')
    
    
    def write_to_file(fname):
        with open(fname, 'w+') as fin:
            fin.write(pyperclip.paste())
    
    
    def format_data_from_file(fname):
        riven_database = dict()
        with open(fname, 'r') as fout:
            data = fout.read().split('\n')
            start_ind = data.index('Riven Name\tAvg Price\tDispo')
            formatted_data = data[start_ind + 1:]
            formatted_data = list(filter(None, formatted_data))
    
            for item in formatted_data:
                temp = item.split('\t')
                riven_database.update({temp[0]: [temp[1], temp[2]]})
    
            return riven_database
    
    
    def ask_user_and_check(riven_dict):
        print("Which weapon would you like to look up for?")
        while True:
            decision = input(">>> ")
            if decision.upper() not in riven_dict.keys():
                print("Weapon name not found. Try again.")
                decision = input(">>> ")
            else:
                print("You have picked {} weapon to check.".format(decision.upper()))
                break
    
        return decision.upper()
    
    
    def print_output(decision, riven_dict):
        print("Name of the weapon: {}".format(decision))
        print("Average riven mod price: {} platinum".format(riven_dict[decision][0]))
        print("Riven disposition of picked weapon: {}".format(riven_dict[decision][1]))
    
    
    def quit_or_loop_again():
        print("Do you want to search again or quit?")
        print("To search again input any character, to quit input [x] or [X].")
        decision = input(">>> ")
        if decision in ['x', 'X']:
            print('Good bye.')
        else:
            main()
    
    
    def main():
        greet()
        open_browser_get_to_clipboard()
        write_to_file('rawdata.txt')
        riven_database = format_data_from_file('rawdata.txt')
        decision = ask_user_and_check(riven_database)
        print_output(decision, riven_database)
        quit_or_loop_again()
    
    
    if __name__ == '__main__':
        main()
    

    我想我会把它留在这里,也许有人会从中取出一些东西,我怀疑这一切是如何运作的。如果用户执行关闭浏览器或更改浏览器选项卡等任何操作,它肯定不会很漂亮并且会失败。还是花了我一些工作,我有点自豪我甚至以这样的方式做到了。我使用的模块非常有趣并且沿途学到了新的东西,我想这就是这个。