我正在尝试以编程方式做一些必然涉及获取“开发人员工具”→网络→媒体日志的事情。
我就不告诉你细节了,长话短说,我需要访问数千个页面,如下所示:https://music.163.com/#/song?id=ID
, where ID
等号后面是一个数字。
如果你打开这样一个页面,就会有一个播放按钮,该按钮会触发一个javascript,加载整个页面中没有引用的音乐文件,并播放该文件。
(注:部分歌曲可能需要中文IP,部分歌曲可能需要VIP账号。)
例如这个页面:https://music.163.com/#/song?id=32477986 https://music.163.com/#/song?id=32477986,它应该看起来像这样:
如果您单击蓝色按钮,则会触发 javascript,并且音乐文件将由 javascript 加载并播放。该音乐文件不会成为网页中的元素,因此无法直接抓取find_element*
方法。
但我找到了一种方法来找到音乐文件的地址。
在 Firefox 中,按 F12 打开检查器/“开发人员工具”,单击网络,然后单击媒体。点击蓝色按钮,会出现多个相同文件名的请求,文件名会匹配^[0-9a-f]+\.m4a
,并且域可能不同。
像这样:
单击任何记录,您将找到其地址,其中任何一个都可以,如下所示:
我目前正在尝试找出如何以编程方式模拟这个过程。
我用谷歌搜索了这个:,并没有找到我要找的东西,这正是我所期望的。我发布这个链接是为了展示我的研究成果,以及谷歌如何不理解你正在尝试搜索的内容的含义。
无论如何,我偶然发现了这一点:https://www.rkengler.com/how-to-capture-network-traffic-when-scraping-with-selenium-and-python/ https://www.rkengler.com/how-to-capture-network-traffic-when-scraping-with-selenium-and-python/
并用这些进行了测试:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
capabilities = DesiredCapabilities.CHROME
capabilities["goog:loggingPrefs"] = {'performance': "ALL"}
driver = webdriver.Chrome(desired_capabilities=capabilities)
wait = WebDriverWait(driver, 15)
driver.get('https://music.163.com/#/song?id=32477986')
iframe = driver.find_element_by_xpath('//iframe[@id="g_iframe"]')
driver.switch_to.frame(iframe)
wait.until(EC.visibility_of_element_located((By.XPATH, '//div[2]/div/a[1]')))
play = driver.find_element_by_xpath('//div[2]/div/a[1]')
play.click()
time.sleep(10)
driver.get_log('performance')
它有效,但输出太宽泛,我更喜欢使用 Firefox。
然后我试图找到所有有效的loggingPrefs
使用谷歌的选项:,不幸的是,但不出所料,我什么也没找到,除了browser:ALL
and driver:ALL
.
我找不到任何指定所有可能的开关的文档。
但我想也许我已经找到了一种模式,性能是检查器/开发工具中的一个选项卡,而网络是另一个选项卡。
所以我替换了两次出现的'performance'
with 'network'
并再次运行代码:
InvalidArgumentException: Message: invalid argument: log type 'network' not found
(Session info: chrome=89.0.4389.90)
这就是我得到的。
无论如何,这就是我整理的:
import os
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
options = Options()
options.headless = True
path = (os.environ['APPDATA'] + '\Mozilla\Firefox\Profiles\Selenium').replace('\\', '/')
profile = webdriver.FirefoxProfile(path)
profile.set_preference("media.volume_scale", "0.0")
capabilities = DesiredCapabilities.FIREFOX
capabilities["loggingPrefs"] = {'performance': 'ALL'}
Firefox = webdriver.Firefox(firefox_profile=profile, desired_capabilities=capabilities, options=options)
wait = WebDriverWait(Firefox, 15)
Firefox.get('https://music.163.com/#/song?id=32477986')
iframe = Firefox.find_element_by_xpath('//iframe[@id="g_iframe"]')
Firefox.switch_to.frame(iframe)
wait.until(EC.visibility_of_element_located((By.XPATH, '//div[2]/div/a[1]')))
play = Firefox.find_element_by_xpath('//div[2]/div/a[1]')
play.click()
time.sleep(10)
Firefox.get_log('performance')
这就是它失败的原因:
WebDriverException: Message: HTTP method not allowed
我如何使用 Python selenium 获取网络→媒体日志?我什至无法使日志记录首选项起作用。我发现的所有内容都使用“loggingPrefs”键,正如您所见,它不起作用。我好像依稀记得gecko:loggingPrefs
但我无法通过谷歌搜索找到任何东西"gecko:loggingPrefs"
.
还有这条评论:使用 Selenium 从 Firefox 获取 console.log 输出 https://stackoverflow.com/questions/23231931/getting-console-log-output-from-firefox-with-selenium#comment72831205_23231931提到 driver.get_log('browser') 将不再工作。但尚不清楚它是否仅适用于browser
或所有日志。
如何获取 Firefox 检查器日志以及如何将其范围缩小到网络→媒体选项卡?
我真的很抱歉,如果我没有表现出足够的研究努力,我到底如何在不使用谷歌的情况下在线研究一些东西呢?难道您从自己使用 Google 的经验中还不够了解吗?Google 永远不会理解您搜索词的含义,它只会查找包含关键字的文档,其中关键字随机散布在文档中,并且结果甚至不必包含所有内容关键词!
谷歌确实是一个糟糕的研究工具,我真的没有什么比谷歌更好的了。因此,如果这还不够,那么我不知道有什么可以算作足够的研究工作。
那么如何使用 Python 3.9.5 selenium 在 Firefox 中获取检查器→网络→媒体日志?
谷歌引导我来到这里,坦率地说,现场搜索引擎甚至比谷歌还要糟糕。我找不到我正在寻找的答案,这正是我在这里提出问题的原因。
经过更多研究,我终于发现了一些东西:https://stackoverflow.com/a/65538568/15290516 https://stackoverflow.com/a/65538568/15290516
这个答案让我离我的目标又近了一步,但我对 javascript 一无所知,测试返回:
JavascriptException: Message: Cyclic object value
但它确实指出了正确的方向,解决方案应该包括.execute_script()
为了完成工作,但我不知道命令应该是什么,我尝试谷歌搜索:,亲自看看它返回什么。
嗯,我设法用 Chrome 获取性能日志并将其重定向到一个文本文件,我将其上传到谷歌云端硬盘 https://drive.google.com/file/d/1ml2GXi5wuHedROWLHsoJO7jacC7DJnTI/view?usp=sharing.
我已经在文件中找到了地址(Notepad++搜索.m4a
),但我不知道如何以编程方式将结果过滤到与音乐文件相关的请求。
我想,现在我会被 Chrome 和性能日志困住。
但我真的不知道如何过滤请求以仅获取相关请求。那怎么办呢?