具有强大查询功能的网页抓取
Webscraping with powerquery
我正在尝试使用 Powerquery 从 Excel 2016 年的网站获取数据,但我无法让它工作。服务器 returns 一个错误页面。当我将同一个 cookie 传递到同一个 asp 页面时,我确实在 Chrome 和 Postman(Chrome 应用程序)中获得了我想要的页面。
代码:
let
Source = Web.Page(Web.Contents("http://portal.icuregswe.org/utdata/_render.aspx", [Headers=[Cookie="__utmt=1; ASP.NET_SessionId=wr4drsm5nqctyk55qcecgiap; __utma=223509914.878319927.1493184252.1493492055.1493534562.4; __utmb=223509914.3.10.1493534562; __utmc=223509914; __utmz=223509914.1493534562.4.4.utmcsr=icuregswe.org|utmccn=(referral)|utmcmd=referral|utmcct=/sv/Utdata/Utdataportal-Ny/; __utma=187689776.292092926.1493485249.1493492045.1493534550.3; __utmb=187689776.3.10.1493534550; __utmc=187689776; __utmz=187689776.1493485249.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); ASP.NET_SessionId=wr4drsm5nqctyk55qcecgiap; __utma=223509914.878319927.1493184252.1493492055.1493534562.4; __utmb=223509914.3.10.1493534562; __utmc=223509914; __utmz=223509914.1493534562.4.4.utmcsr=icuregswe.org|utmccn=(referral)|utmcmd=referral|utmcct=/sv/Utdata/Utdataportal-Ny/"]])),
Data0 = Source{0}[Data]
in
Data0
DOM结构:
错误信息:
System.NullReferenceException: Object reference not set to an instance of an object.
at _render.Page_Load(Object sender, EventArgs e)
at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
怀疑服务器缺少生成页面的一些输入(使用 Chrome 中的开发工具可以看到对服务器进行了多次调用,我不确定它在这方面是如何工作的).
主页在这里:
http://portal.icuregswe.org/utdata/
通过菜单访问报告,例如:Rapporter->Produktion->Vårdtid->Vårddygn summa
有什么想法吗?
编辑:我之前以为我已经弄明白了,但是当我试图在同一网站上抓取不同的报告时,我意识到它不起作用。我想出了这个涉及 VB-脚本和 Power Query 的解决方案:
要使用,需要通过选择 "Urval"、选择时间段并选择报告从站点获取带有会话 ID 的 cookie 值。这将 return 一个带有会话 ID 的 cookie,将此值复制到单元格 B4(必须命名为 cookievalue)。设置完成后,单击更新按钮即可执行下面的 VB 脚本。这将调用网站为当前会话 ID 设置报告类型,然后更新将从网站获取 CSV 的 Power Query。
sheet是命名参数。
Excel screenshot
从站点获取 CSV 的 Power Query:
let
cookiestr = Excel.CurrentWorkbook(){[Name="cookievalue"]}[Content]{0}[Column1],
Source = Excel.Workbook(Web.Contents("http://portal.icuregswe.org/utdata/ExcelExport.aspx", [Headers=[Cookie=cookiestr]]), null, true),
#"SIR-rapport_Sheet" = Source{[Item="SIR-rapport",Kind="Sheet"]}[Data]
in
#"SIR-rapport_Sheet"
VB 调用网站并设置报告类型和更新 Power Query 的脚本:
Sub Button1_Click()
Dim URL As String
URL = Sheets("parameters").Range("B2")
Dim param As String
param = Sheets("parameters").Range("B3")
Dim cookie As String
cookie = Sheets("parameters").Range("B4")
Dim w As New WinHttp.WinHttpRequest
w.Open "POST", URL & param, False
w.setRequestHeader "Cookie", cookie
w.send qs
'Macro to update Power Query script(s)
Dim lTest As Long, cn As WorkbookConnection
On Error Resume Next
For Each cn In ThisWorkbook.Connections
lTest = InStr(1, cn.OLEDBConnection.Connection, "Provider=Microsoft.Mashup.OleDb.1", vbTextCompare)
If Err.Number <> 0 Then
Err.Clear
Exit For
End If
If lTest > 0 Then cn.Refresh
Next cn
End Sub
来源:
- Set/Get Web Cookies
- http://www.excelguru.ca/blog/2014/10/22/refresh-power-query-with-vba/
我正在尝试使用 Powerquery 从 Excel 2016 年的网站获取数据,但我无法让它工作。服务器 returns 一个错误页面。当我将同一个 cookie 传递到同一个 asp 页面时,我确实在 Chrome 和 Postman(Chrome 应用程序)中获得了我想要的页面。
代码:
let
Source = Web.Page(Web.Contents("http://portal.icuregswe.org/utdata/_render.aspx", [Headers=[Cookie="__utmt=1; ASP.NET_SessionId=wr4drsm5nqctyk55qcecgiap; __utma=223509914.878319927.1493184252.1493492055.1493534562.4; __utmb=223509914.3.10.1493534562; __utmc=223509914; __utmz=223509914.1493534562.4.4.utmcsr=icuregswe.org|utmccn=(referral)|utmcmd=referral|utmcct=/sv/Utdata/Utdataportal-Ny/; __utma=187689776.292092926.1493485249.1493492045.1493534550.3; __utmb=187689776.3.10.1493534550; __utmc=187689776; __utmz=187689776.1493485249.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); ASP.NET_SessionId=wr4drsm5nqctyk55qcecgiap; __utma=223509914.878319927.1493184252.1493492055.1493534562.4; __utmb=223509914.3.10.1493534562; __utmc=223509914; __utmz=223509914.1493534562.4.4.utmcsr=icuregswe.org|utmccn=(referral)|utmcmd=referral|utmcct=/sv/Utdata/Utdataportal-Ny/"]])),
Data0 = Source{0}[Data]
in
Data0
DOM结构:
错误信息:
System.NullReferenceException: Object reference not set to an instance of an object.
at _render.Page_Load(Object sender, EventArgs e)
at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
怀疑服务器缺少生成页面的一些输入(使用 Chrome 中的开发工具可以看到对服务器进行了多次调用,我不确定它在这方面是如何工作的).
主页在这里: http://portal.icuregswe.org/utdata/
通过菜单访问报告,例如:Rapporter->Produktion->Vårdtid->Vårddygn summa
有什么想法吗?
编辑:我之前以为我已经弄明白了,但是当我试图在同一网站上抓取不同的报告时,我意识到它不起作用。我想出了这个涉及 VB-脚本和 Power Query 的解决方案:
要使用,需要通过选择 "Urval"、选择时间段并选择报告从站点获取带有会话 ID 的 cookie 值。这将 return 一个带有会话 ID 的 cookie,将此值复制到单元格 B4(必须命名为 cookievalue)。设置完成后,单击更新按钮即可执行下面的 VB 脚本。这将调用网站为当前会话 ID 设置报告类型,然后更新将从网站获取 CSV 的 Power Query。
sheet是命名参数。
Excel screenshot
从站点获取 CSV 的 Power Query:
let
cookiestr = Excel.CurrentWorkbook(){[Name="cookievalue"]}[Content]{0}[Column1],
Source = Excel.Workbook(Web.Contents("http://portal.icuregswe.org/utdata/ExcelExport.aspx", [Headers=[Cookie=cookiestr]]), null, true),
#"SIR-rapport_Sheet" = Source{[Item="SIR-rapport",Kind="Sheet"]}[Data]
in
#"SIR-rapport_Sheet"
VB 调用网站并设置报告类型和更新 Power Query 的脚本:
Sub Button1_Click()
Dim URL As String
URL = Sheets("parameters").Range("B2")
Dim param As String
param = Sheets("parameters").Range("B3")
Dim cookie As String
cookie = Sheets("parameters").Range("B4")
Dim w As New WinHttp.WinHttpRequest
w.Open "POST", URL & param, False
w.setRequestHeader "Cookie", cookie
w.send qs
'Macro to update Power Query script(s)
Dim lTest As Long, cn As WorkbookConnection
On Error Resume Next
For Each cn In ThisWorkbook.Connections
lTest = InStr(1, cn.OLEDBConnection.Connection, "Provider=Microsoft.Mashup.OleDb.1", vbTextCompare)
If Err.Number <> 0 Then
Err.Clear
Exit For
End If
If lTest > 0 Then cn.Refresh
Next cn
End Sub
来源:
- Set/Get Web Cookies
- http://www.excelguru.ca/blog/2014/10/22/refresh-power-query-with-vba/