使用python / selenium保存完整的网页(包括CSS,图像) - python

我正在使用Python / Selenium将遗传序列提交到在线数据库,并希望保存返回的完整页面。以下是使我获得所需结果的代码:

from selenium import webdriver

URL = 'https://blast.ncbi.nlm.nih.gov/Blast.cgi?PROGRAM=blastx&PAGE_TYPE=BlastSearch&LINK_LOC=blasthome'
SEQUENCE = 'CCTAAACTATAGAAGGACAGCTCAAACACAAAGTTACCTAAACTATAGAAGGACAGCTCAAACACAAAGTTACCTAAACTATAGAAGGACAGCTCAAACACAAAGTTACCTAAACTATAGAAGGACAGCTCAAACACAAAGTTACCTAAACTATAGAAGGACA' #'GAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGA'
CHROME_WEBDRIVER_LOCATION = '/home/max/Downloads/chromedriver' # update this for your machine

# open page with selenium
# (first need to download Chrome webdriver, or a firefox webdriver, etc)
driver = webdriver.Chrome(executable_path=CHROME_WEBDRIVER_LOCATION)
driver.get(URL)
time.sleep(5)

# enter sequence into the query field and hit 'blast' button to search
seq_query_field = driver.find_element_by_id("seq")
seq_query_field.send_keys(SEQUENCE)

blast_button = driver.find_element_by_id("b1")
blast_button.click()
time.sleep(60)

到那时,我有了一个页面,可以手动单击“另存为”,并获取一个本地文件(带有相应的image / js资产文件夹),该文件可让我在本地查看整个返回的页面(减去从中动态生成的内容)向下滚动页面,这很好)。我以为有一种简单的方法可以在python / selenium中模仿这个“另存为”功能,但是还没有找到。保存下面页面的代码仅保存html,而不会给我留下一个看起来像在Web浏览器中一样的本地文件,图像等。

content = driver.page_source
with open('webpage.html', 'w') as f:
    f.write(content)

我也找到了this question/answer on SO,但是被接受的答案只是显示了“另存为”框,并且没有提供一种单击它的方法(正如两个评论者指出的那样)

有没有一种简单的方法可以使用python“将[整页]另存为”?理想情况下,我更喜欢使用硒的答案,因为硒使爬网部分非常简单,但是如果有更好的工具可以使用此库,我愿意使用其他库。或者,也许我只需要指定要在代码中下载的所有图像/表,而没有模拟右键单击“另存为”功能的捷径?

更新-詹姆斯回答的后续问题
因此,我运行了James的代码以生成page.html(及相关文件),并将其与通过手动单击另存为得到的html文件进行了比较。通过James脚本保存的page.html很棒,可以满足我的所有需求,但是在浏览器中打开它时,它还会显示很多额外的格式化文本,这些文本隐藏在手动保存的页面中。请参阅附件的屏幕截图(左侧是手动保存的页面,右侧是脚本保存的页面,带有额外的格式化文本)。
使用python / selenium保存完整的网页(包括CSS,图像) - python

这对我来说尤其令人惊讶,因为James脚本保存的页面原始html似乎表明这些字段仍应隐藏。参见例如下面的html,在两个文件中看起来都一样,但是有争议的文本仅出现在由James脚本保存的页面上的浏览器渲染页面中:

<p class="helpbox ui-ncbitoggler-slave ui-ncbitoggler" id="hlp1" aria-hidden="true">
These options control formatting of alignments in results pages. The
default is HTML, but other formats (including plain text) are available.
PSSM and PssmWithParameters are representations of Position Specific Scoring Matrices and are only available for PSI-BLAST. 
The Advanced view option allows the database descriptions to be sorted by various indices in a table.
</p>

知道为什么会这样吗?

参考方案

如您所述,Selenium无法与浏览器的上下文菜单进行交互以使用Save as...,因此,您可以使用 pyautogui 之类的外部自动化库来代替。

pyautogui.hotkey('ctrl', 's')
time.sleep(1)
pyautogui.typewrite(SEQUENCE + '.html')
pyautogui.hotkey('enter')

此代码通过其键盘快捷键Save as...打开CTRL+S窗口,然后按Enter将网页及其资产保存到默认下载位置。该代码还将文件命名为序列,以便为其赋予唯一名称,尽管您可以针对用例进行更改。如果需要,您可以通过使用Tab和箭头键进行一些额外的操作来另外更改下载位置。

在Ubuntu 18.10上测试;根据您的操作系统,您可能需要修改发送的组合键。

完整代码,其中还添加了条件等待以提高速度:

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.expected_conditions import visibility_of_element_located
from selenium.webdriver.support.ui import WebDriverWait
import pyautogui

URL = 'https://blast.ncbi.nlm.nih.gov/Blast.cgi?PROGRAM=blastx&PAGE_TYPE=BlastSearch&LINK_LOC=blasthome'
SEQUENCE = 'CCTAAACTATAGAAGGACAGCTCAAACACAAAGTTACCTAAACTATAGAAGGACAGCTCAAACACAAAGTTACCTAAACTATAGAAGGACAGCTCAAACACAAAGTTACCTAAACTATAGAAGGACAGCTCAAACACAAAGTTACCTAAACTATAGAAGGACA' #'GAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGAGAAGA'

# open page with selenium
# (first need to download Chrome webdriver, or a firefox webdriver, etc)
driver = webdriver.Chrome()
driver.get(URL)

# enter sequence into the query field and hit 'blast' button to search
seq_query_field = driver.find_element_by_id("seq")
seq_query_field.send_keys(SEQUENCE)

blast_button = driver.find_element_by_id("b1")
blast_button.click()

# wait until results are loaded
WebDriverWait(driver, 60).until(visibility_of_element_located((By.ID, 'grView')))

# open 'Save as...' to save html and assets
pyautogui.hotkey('ctrl', 's')
time.sleep(1)
pyautogui.typewrite(SEQUENCE + '.html')
pyautogui.hotkey('enter')

在返回'Response'(Python)中传递多个参数 - python

我在Angular工作,正在使用Http请求和响应。是否可以在“响应”中发送多个参数。角度文件:this.http.get("api/agent/applicationaware").subscribe((data:any)... python文件:def get(request): ... return Response(seriali…

使用python statsmodel进行多元线性回归 - python

在R中,可以执行多元线性回归,例如temp = lm(log(volume_1[11:62])~log(price_1[11:62])+log(volume_1[10:61])) 在Python中,可以使用R样式公式,所以我认为下面的代码应该也能正常工作,import statsmodels.formula.api as smf import pandas …

Python exchangelib在子文件夹中读取邮件 - python

我想从Outlook邮箱的子文件夹中读取邮件。Inbox ├──myfolder 我可以使用account.inbox.all()阅读收件箱,但我想阅读myfolder中的邮件我尝试了此页面folder部分中的内容,但无法正确完成https://pypi.python.org/pypi/exchangelib/ 参考方案 您需要首先掌握Folder的myfo…

R'relaimpo'软件包的Python端口 - python

我需要计算Lindeman-Merenda-Gold(LMG)分数,以进行回归分析。我发现R语言的relaimpo包下有该文件。不幸的是,我对R没有任何经验。我检查了互联网,但找不到。这个程序包有python端口吗?如果不存在,是否可以通过python使用该包? python参考方案 最近,我遇到了pingouin库。

Python ThreadPoolExecutor抑制异常 - python

from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED def div_zero(x): print('In div_zero') return x / 0 with ThreadPoolExecutor(max_workers=4) as execut…