【问题标题】:BeautifulSoup code to Click a Link on a site and then Copy/Paste All Text On Screen to Raw Text FileBeautifulSoup 代码单击网站上的链接,然后将屏幕上的所有文本复制/粘贴到原始文本文件
【发布时间】:2022-07-02 02:29:08
【问题描述】:

嘿 StackExchange 我需要一些帮助来完成我通过 Linux shell 在 BeagleBoneBlack 上运行的一小段 Python 代码。这是从 PSKReporter.info 将一些原始数据保存到文本文件的两个脚本中的第一个。我已经完成了将使用此数据的第二个解析脚本,但现在希望原始数据拉取也使用 Python!

我过去曾尝试过使用 BeautifulSoup,您可以在下面的代码中看到,但我不知道它是否能够实现我正在寻找的功能。特别是我不知道如何在链接上进行交互(单击)以显示更多数据。过去我用 BeautifulSoup 做的最多的是搜索粗体标签之类的东西,然后从中提取显示的数据片段。

也许我需要一些其他的包/功能,但也许有人也可以教我一些关于 BeautifulSoup 的新知识!

我想要 Python 代码做的只是:

  1. 转到此链接https://pskreporter.info/pskmap.html?preset&callsign=en71&what=grid&mode=FT8&band=12000000-16000000&timerange=900&distunit=miles&mapCenter=35.71878123231818,14.756871723642343,2.292836140088628

注意:这些设置应该已经通过链接设置,例如,20m、信号、send/rcvd by、方格、EN71、使用 FT8,在过去 15 分钟内。

  1. 如果存在,请单击“(显示日志)”的超链接。如果它不存在,我们可以退出并完成。这部分是在下面的代码中工作的,至少通过检查“if str(soup).find(“logbook”) != -1”来验证“(show logbook)”是否存在。这一步是我最不确定的部分,我之前从未在 BeautifulSoup 中进行过“点击”或交互,只是提取文本以供以后解析。我们甚至可以在没有 GUI 和 Web 浏览器与链接交互的情况下显示此表吗?真正让我感到困惑的是,在 BBB 上,我正在从 Linux shell 运行这个 Python 代码,没有可点击的链接,实际上不会“显示”任何内容,但我想这仍然是可能的。

  2. 执行“Ctrl-A”然后“Ctrl-C”之类的命令来复制整个屏幕的原始文本。

  3. 将其存储到变量中,或者将其打印到原始文本文件中。如果你把它保存了,我可以自己把它写成一个 .txt 文件。

输出 .txt 文件示例如下所示,位于我开始的代码模板下方。我已经完成了 Python 代码,它将获取这个原始文本文件,在“Txmtr Rcvr Band Mode Distance Time (UTC)”之后找到第一行数据,将所有数据存储到单独的数组中,进行自定义解析和统计,并在它发现的某些条件下给我发短信!该代码运行良好,去年夏天我一直在使用它来通知我 6m 魔术波段打开时的情况,这样我就可以打开收音机并进行一些联系!

我爸爸以前在 Windows 机器上使用一些 AutoHotkey 脚本来执行初始原始数据提取,并通过 FTP 将原始数据发送给我到我的 BeagleBoneBlack。在 BBB 上,我使用 Python 来完成其余的解析,而不需要 GUI。他的代码停止工作,我认为我们可以通过将其全部放在 BBB 上来改进它,但是我正在努力解决可能是单击和复制所有数据的简单步骤!

忽略仅在一次迭代后就爆发的奇数无限循环。这是我从其他代码中偷来的!

提前非常感谢您。我已经潜伏了很长时间,但最终决定创建一个帐户并发布,因为我真的希望这段代码再次工作!

我现在得到的Bare Bones Pseudocode(确实可以找到可点击的链接是否存在):

# Import requests (to download the page)
import requests
# Import BeautifulSoup (to parse what we download)
from bs4 import BeautifulSoup

print('Setup complete.')

# while this is true (it is true by default),
while True:
    print('This is the beginning of the program. Checking PSKReporter.')
    # set the url
    url = "https://pskreporter.info/pskmap.html?preset&callsign=en71&what=grid&mode=FT8&band=12000000-16000000&timerange=900&distunit=miles&mapCenter=35.71878123231818,14.756871723642343,2.292836140088628"
    # set the headers like we are a browser,
    headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
    # download the homepage
    response = requests.get(url, headers=headers)
    # parse the downloaded homepage and grab all text, then,
    soup = BeautifulSoup(response.text, "lxml")
    
    # if the result is NOT equal to -1, then it found it!
    if str(soup).find("logbook") != -1: 
        print('Found (show logbook), clicking link now')
        #click code here
        
        
        print('Saving Raw Data to "PSKDataFile.txt"')
        #copy and paste all data to raw .txt file here     
        
        
        #break to leave infinite while loop
        break

            
    # but if the word "logbook" didn't appear
    else: #must have been -1
        print('Didnt find the logbook. Try another data search with a different band, different grid square, etc..')
      
            #break to leave the infinite while loop
        break

原始 .txt 数据文件示例:

On 
20m
, show 
signals
 
sent/rcvd by
 
grid square
 
en71
 using 
FT8
 over the last 
15 minutes
  Display options Permalink
Automatic refresh in 4 minutes. Small markers are the 128 transmitters (show logbook) heard at EN71.
There are 793 active FT8 monitors on 20m. Show all FT8 on all bands. Show all on all bands. Legend

Download (ADIF) last 24 hours, last week
Txmtr   Rcvr    Band    Mode    Distance    Time (UTC)
W7FRD   KD9ROL  20m FT8 1360 miles  00:13:27
KF0FSJ  N9AJD   20m FT8 952 miles   00:13:12
N5VJV   KD9ROL  20m FT8 829 miles   00:13:11
KF0FSJ  KD9ROL  20m FT8 957 miles   00:13:11
KC5HXK  KD9ROL  20m FT8 1000 miles  00:13:11
PY2RFL  KD9ROL  20m FT8 4943 miles  00:13:11
LU8LTT  AA9DU   20m FT8 5024 miles  00:12:57
KJ7RGW  AA9DU   20m FT8 1833 miles  00:12:57
KC0FGX  AA9DU   20m FT8 408 miles   00:12:57
W9BFP   AA9DU   20m FT8 1862 miles  00:12:57
VE2FVV  AA9DU   20m FT8 997 miles   00:12:27
K0CAH   KD9ROL  20m FT8 1045 miles  00:12:26
KB5GA   N9AJD   20m FT8 823 miles   00:12:26
KD9ROL  AA7NM   20m FT8 1889 miles  00:12:15
KD9ROL  KD1ELK  20m FT8 1564 miles  00:12:13
WI0R    N9AJD   20m FT8 1037 miles  23:58:41
KD5MZV  KB8CBY  20m FT8 824 miles   23:58:41
KD5MZV  AA9DU   20m FT8 761 miles   23:58:41
Statistics — Comments to Philip Gladstone — Online discussions — Reception records: 25,686,714,752 — Hosting by Fast Serv Networks, LLC
PSKREPORTER.INFO

【问题讨论】:

  • 问题不在于 BeautifulSoup。问题是requests 没有获得实时连接。它获取页面的原始 HTML。它不执行任何Javascript。如果您可以生成静态 HTML 来模拟获取下一页,那很好。否则,你将不得不切换到 Selenium,你正在驱动一个真正的浏览器。
  • 我有过类似的想法,因为我认为一切都只是得到一个原始的 HTML,而且那时它只是非交互式文本。我正在考虑安装 Selenium 和 Firefox 驱动程序。希望我能尽快让它工作并开始测试它打开页面和点击的能力!看起来可能有一些我正在寻找的代码:link = driver.find_element_by_link_text('Logbook') link.click()
  • 我一直在尝试安装 Selenium 和 WebDriver (Firefox/Chrome),但收效甚微。我想我已经弄清楚了 Firefox 的所有 PATH 情况,因为我可以在任何地方键入“firefox”,但我得到一个运行时错误“Exec format error”。当我运行我的 Python 代码到使用 Geckodriver 打开 Firefox 时,这与我最终遇到的错误相同。在我的 BBB 32 位上运行正常的 Firefox 将是一个好的开始。 32 位不再支持 Chrome。切换到 RaspBerry Pi 3(64 位)可能是让 Selenium 为这种方法工作的唯一选择。

标签: python url beautifulsoup text-files


【解决方案1】:

您看到的数据是通过 JavaScript 加载的,因此您可以使用 requests/re/json 模块对其进行解析。例如:

import re
import json
import requests
from bs4 import BeautifulSoup


api_url = "https://pskreporter.info/cgi-bin/pskquery5.pl"


query = {
    "encap": "1",
    "callback": "doNothing",
    "statistics": "1",
    "noactive": "1",
    "nolocator": "1",
    "flowStartSeconds": "-900",
    "frange": "12000000-16000000",
    "mode": "FT8",
    "modify": "grid",
    "callsign": "en71",
}

soup = BeautifulSoup(requests.get(api_url, params=query).content, "html.parser")
d = re.search(r"doNothing\((.*)\);", soup.js.contents[0], flags=re.S).group(1)
d = json.loads(d)

# pretty print
print(json.dumps(d, indent=4))

打印:


...

    "time2-activeReceivers-cache": 0.005166,
    "activeReceiver": [
        {
            "callsign": "8P6PE",
            "locator": "GK03fd",
            "frequency": 14075582,
            "region": "Saint George",
            "DXCC": "Barbados",
            "decoderSoftware": "JTDX v2.2.158 3c64ff",
            "mode": "FT8"
        },
        {
            "callsign": "K7IIJ",
            "locator": "CN85pm21tv",
            "frequency": 14075222,
            "region": "Oregon",
            "DXCC": "United States",
            "decoderSoftware": "WSJT-X v2.5.2 68dc11",
            "mode": "FT8"
        },

...

【讨论】:

  • 这看起来几乎正是我所需要的 Andrej 并且给了我更多思考的概念!我喜欢您摆脱永久链接的方式,并表明我们实际上可以与 pskquery 交互以更改我们想要查看的数据。您知道要在 re.search 中修改哪些参数以提取单个部分吗?您已经获得了“activeReceiver”部分的部分打印输出,但还有其他部分,例如“receptionReport”、“senderSearch”等。这非常接近能够磨练最相关的部分,然后解析数据将是小菜一碟!
  • 在最坏的情况下,如果我不能让 json 过滤更多一点,看起来我想要从原始帖子中获得的“(显示日志)”超链接信息在“接收报告”,这是最后打印的内容。解析到这一点并开始提取我想要的数据应该不会太糟糕,因为它清楚地标有好名字。 flowStartSeconds 的 UTC 时间有趣的是在 Unix 纪元时间!这里没有距离,但可以用 Grid Squares 计算,这是我爸爸最近对不同算法着迷的东西!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多