我有一个要保存为PDF的食谱的URL列表,然后我对该站点的订阅用尽了。使用Xenu Link Sleuth收集URL,将其保存到Excel电子表格中,进行调整以进行清理,删除重复项并导出到以Tab分隔的txt文件中。
一个朋友编写了一个AutoHotKey脚本,该脚本将使用URL并在Chrome中使用“打印为PDF”选项,但这存在问题。除了由于脚本需要控制鼠标而使我的计算机无法运行之外,它经常通过某种方式尝试保存两次相同的URL(即使没有重复的链接)或只是不保存任何内容而无法正常工作。
下面是我朋友写的脚本。这似乎对他最有效,但对我来说,在这种状态下将不会保存任何东西。在Sleep 7000之后,我添加了另一个Send {Enter},以便激活另存为对话框中用于保存PDF的Save按钮以及另一个较短的Sleep。
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
Loop, read, %A_ScriptDir%\CookSpread.txt
{
StringSplit, LineArray, A_LoopReadLine, %A_Tab%
URL := LineArray1
Run, %URL%
Sleep 7000
Click 3407, 241
Sleep 3000
Send {Enter}
Sleep 7000
Send ^{F4}
Sleep 4000
}
我做了一些修改。一个是我减少了每个步骤之间的时间(也许是问题所在)。我还添加了单击以选择要与配方一起打印的营养信息。您也可以在结尾处看到我的第二个Enter。
Sleep 6000
Click 1500, 550
Sleep 500
Click 1480, 220
Sleep 3000
Send {Enter}
Sleep 1000
Send {Enter}
Sleep 1000
Send ^{F4}
Sleep 2000
}
我希望它能正常运行,从文本文件中获取链接,在浏览器中将其打开,将鼠标移到打印按钮(单击)上,这将打开“打印”界面。然后按Enter键单击“保存”按钮,然后按Enter键单击“保存”按钮,保存文件,然后关闭当前的Chrome选项卡,然后重新开始。
发生的事情是,它适合20个或30个URL,但是随后在保存时发生了什么,这表示该文件已经存在,并询问我是否要覆盖它。在脚本继续尝试执行其余步骤的同时,此窗口保持打开状态,因此其他任何事情都不会完成。最终发生的事情是打开了数百个选项卡,因为URL仍在浏览器中打开。
我想知道是否有人知道如何纠正此问题,或者他们是否知道另一种方法来完成此操作。一个独立的GUI应用程序或可以在后台使用我的登录凭据的东西是理想的选择,因为AutoHotKey脚本使我的计算机在运行时无法使用。但是,如果有人能弄清楚如何进行这项工作,那对我来说已经足够了。
答案 0 :(得分:1)
尝试:
全部替换
此代码中的“ D:\ Downloads ” 带有文件夹路径的程序将保存打印的URL
在打印设置中,“ 目标”必须为“ 另存为PDF ”
#NoEnv
#SingleInstance Force
SetWorkingDir %A_ScriptDir%
ModernBrowsers := "Chrome_WidgetWin_0,Chrome_WidgetWin_1,MozillaWindowClass"
LegacyBrowsers := "IEFrame,OperaWindowClass"
FileCreateDir, D:\Downloads\Newly created
FileMove, D:\Downloads\*.pdf, D:\Downloads\Newly created\, 1
F1::
If !WinExist("ahk_exe chrome.exe")
Run, chrome.exe
WinWait, ahk_exe chrome.exe
Sleep, 500
Loop, read, %A_ScriptDir%\CookSpread.txt
{
StringSplit, LineArray, A_LoopReadLine, %A_Tab%
URL := LineArray1
Run, chrome.exe "%URL%"
Sleep, 500
Loop
{
WinActivate, ahk_exe chrome.exe
WinWaitActive, ahk_exe chrome.exe, , 1
If !(ErrorLevel)
break
}
Loop
{
OutputURL := GetActiveBrowserURL()
Sleep, 500
If (OutputURL = "")
continue
If (OutputURL = URL)
break
}
Sleep, 500
Loop
{
WinActivate, ahk_exe chrome.exe
WinWaitActive, ahk_exe chrome.exe, , 1
If !(ErrorLevel)
break
}
Send, ^p
Sleep, 500
Loop
{
WinActivate, ahk_exe chrome.exe
WinWaitActive, ahk_exe chrome.exe, , 1
If !(ErrorLevel)
break
}
Sleep, 300
Send, {Enter}
Sleep, 500
WinWait, Save As ahk_exe chrome.exe
Loop
{
WinActivate, Save As ahk_exe chrome.exe
WinWaitActive, Save As ahk_exe chrome.exe, , 1
If !(ErrorLevel)
{
Send, !s
break
}
}
Sleep, 500
Loop
{
FileMove, D:\Downloads\*.pdf, D:\Downloads\Newly created\, 1
Sleep, 500
If !FileExist("D:\Downloads\*.pdf")
{
WinActivate, ahk_exe chrome.exe
WinWaitActive, ahk_exe chrome.exe, , 1
If !(ErrorLevel)
{
Send, ^w
break
}
}
}
Sleep, 500
}
Run D:\Downloads\Newly created
return
; https://www.autohotkey.com/boards/viewtopic.php?t=3702
; Get the URL of the current (active) browser tab
GetActiveBrowserURL(){
global ModernBrowsers, LegacyBrowsers
WinGetClass, sClass, A
If sClass In % ModernBrowsers ; %
Return GetBrowserURL_ACC(sClass)
Else If sClass In % LegacyBrowsers ; %
Return GetBrowserURL_DDE(sClass) ; empty string if DDE not supported (or not a browser)
Else
Return ""
}
; "GetBrowserURL_DDE" adapted from DDE code by Sean, (AHK_L version by maraskan_user)
; Found at
; http://autohotkey.com/board/topic/17633-/?p=434518
GetBrowserURL_DDE(sClass) {
WinGet, sServer, ProcessName, % "ahk_class " sClass ; %
StringTrimRight, sServer, sServer, 4
iCodePage := A_IsUnicode ? 0x04B0 : 0x03EC ; 0x04B0 = CP_WINUNICODE, 0x03EC = CP_WINANSI
DllCall("DdeInitialize", "UPtrP", idInst, "Uint", 0, "Uint", 0, "Uint", 0)
hServer := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", sServer, "int", iCodePage)
hTopic := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "WWW_GetWindowInfo", "int", iCodePage)
hItem := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "0xFFFFFFFF", "int", iCodePage)
hConv := DllCall("DdeConnect", "UPtr", idInst, "UPtr", hServer, "UPtr", hTopic, "Uint", 0)
hData := DllCall("DdeClientTransaction", "Uint", 0, "Uint", 0, "UPtr", hConv, "UPtr", hItem, "UInt", 1, "Uint", 0x20B0, "Uint", 10000, "UPtrP", nResult) ; 0x20B0 = XTYP_REQUEST, 10000 = 10s timeout
sData := DllCall("DdeAccessData", "Uint", hData, "Uint", 0, "Str")
DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hServer)
DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hTopic)
DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hItem)
DllCall("DdeUnaccessData", "UPtr", hData)
DllCall("DdeFreeDataHandle", "UPtr", hData)
DllCall("DdeDisconnect", "UPtr", hConv)
DllCall("DdeUninitialize", "UPtr", idInst)
csvWindowInfo := StrGet(&sData, "CP0")
StringSplit, sWindowInfo, csvWindowInfo, `" ;"; comment to avoid a syntax highlighting issue in autohotkey.com/boards
Return sWindowInfo2
}
GetBrowserURL_ACC(sClass) {
global nWindow, accAddressBar
If (nWindow != WinExist("ahk_class " sClass)) ; reuses accAddressBar if it's the same window
{
nWindow := WinExist("ahk_class " sClass)
accAddressBar := GetAddressBar(Acc_ObjectFromWindow(nWindow))
}
Try sURL := accAddressBar.accValue(0)
If (sURL == "") {
WinGet, nWindows, List, % "ahk_class " sClass ; ; % In case of a nested browser window as in the old CoolNovo (TO DO: check if still needed)
If (nWindows > 1) {
accAddressBar := GetAddressBar(Acc_ObjectFromWindow(nWindows2))
Try sURL := accAddressBar.accValue(0)
}
}
If ((sURL != "") and (SubStr(sURL, 1, 4) != "http")) ; Modern browsers omit "http://"
sURL := "http://" sURL
If (sURL == "")
nWindow := -1 ; Don't remember the window if there is no URL
Return sURL
}
; "GetAddressBar" based in code by uname
; Found at http://autohotkey.com/board/topic/103178-/?p=637687
GetAddressBar(accObj) {
Try If ((accObj.accRole(0) == 42) and IsURL(accObj.accValue(0)))
Return accObj
Try If ((accObj.accRole(0) == 42) and IsURL("http://" accObj.accValue(0))) ; Modern browsers omit "http://"
Return accObj
For nChild, accChild in Acc_Children(accObj)
If IsObject(accAddressBar := GetAddressBar(accChild))
Return accAddressBar
}
IsURL(sURL) {
Return RegExMatch(sURL, "^(?<Protocol>https?|ftp)://(?<Domain>(?:[\w-]+\.)+\w\w+)(?::(?<Port>\d+))?/?(?<Path>(?:[^:/?# ]*/?)+)(?:\?(?<Query>[^#]+)?)?(?:\#(?<Hash>.+)?)?$")
}
; The code below is part of the Acc.ahk Standard Library by Sean (updated by jethrow)
; Found at http://autohotkey.com/board/topic/77303-/?p=491516
Acc_Init()
{
static h
If Not h
h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromWindow(hWnd, idObject = 0)
{
Acc_Init()
If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
Return ComObjEnwrap(9,pacc,1)
}
Acc_Query(Acc) {
Try Return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Acc_Children(Acc) {
If ComObjType(Acc,"Name") != "IAccessible"
ErrorLevel := "Invalid IAccessible Object"
Else {
Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
If DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
Loop %cChildren%
i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
Return Children.MaxIndex()?Children:
} Else
ErrorLevel := "AccessibleChildren DllCall Failed"
}
}