使用Power Query抓取URL不变的多页面数据遇阻求助
PowerBI抓取动态分页招聘网站的问题解决
你已经成功搞定了HSBC这种URL随分页变化的站点,代码逻辑没问题:
(PageStart as text) => let Source = Web.BrowserContents("https://mycareer.hsbc.com/en_GB/external/SearchJobs/?pipelineRecordsPerPage=10&pipelineOffset="&PageStart&""), #"Extracted Table From Html" = Html.Table(Source, {{"Column1", ".article__header__text__title\-\-8 *"}, {"Column2", ".location"}, {"Column3", ".icon\-\-folder + *"}, {"Column4", ".icon\-\-clock + *"}, {"Column5", ".icon\-\-person + *"}, {"Column6", ".icon\-\-calendar + *"}, {"Column7", ".social-share__text"}, {"Column8", ".link\-\-chevron *"}, {"Column9", ".grid .link\-\-chevron:nth-child(1)"}}, [RowSelector=".article\-\-result"]), #"Changed Type" = Table.TransformColumnTypes(#"Extracted Table From Html",{{"Column1", type text}, {"Column2", type text}, {"Column3", type text}, {"Column4", type text}, {"Column5", type text}, {"Column6", type text}, {"Column7", type text}, {"Column8", type text}, {"Column9", type text}}) in #"Changed Type"
但Target印度招聘站这类URL不随分页变化的站点,问题出在会话验证,你直接复制的分页URL没用的原因:
- 这个URL是浏览器在完成初始GeoLocation设置后发送的,单独访问时缺少网站要求的会话Cookie(比如验证过的地理位置标识、会话ID)
- 站点可能还会检查请求头的
Referer(来源页面)、User-Agent等字段,确保请求不是直接从外部发起的
两种可行的解决方法
方法1:用Web.BrowserContents保持会话
PowerBI的Web.BrowserContents会模拟完整的浏览器会话,自动保存Cookie,步骤如下:
- 先加载初始的GeoLocation页面,建立合法会话
- 再访问分页URL,此时会携带之前的会话Cookie
示例代码:
let // 第一步:加载初始页面,完成Geo验证并建立会话 InitialSession = Web.BrowserContents("https://indiajobs.target.com/search-jobs/SetSearchRequestGeoLocation?lat=null&lon=null&IsUsingGeolocation=true&hasHtml5GeoError=false&geoType=ipambientonly"), // 第二步:访问第二页,此时会话已建立,能正常返回数据 Page2 = Web.BrowserContents("https://indiajobs.target.com/search-jobs/results?ActiveFacetID=0&CurrentPage=2&RecordsPerPage=15&Distance=50&RadiusUnitType=0&Keywords=&Location=&ShowRadius=False&IsPagination=False&CustomFacetName=&FacetTerm=&FacetType=0&SearchResultsModuleName=Search+Results&SearchFiltersModuleName=Search+Filters&SortCriteria=0&SortDirection=0&SearchType=5&PostalCode=&ResultsType=0&fc=&fl=&fcf=&afc=&afl=&afcf="), // 提取表格(需要调整CSS选择器为Target站点的实际元素) ExtractedTable = Html.Table(Page2, {{"职位名称", ".job-title"}, {"工作地点", ".location"}}, [RowSelector=".job-listing"]), // 转换数据类型 ChangedType = Table.TransformColumnTypes(ExtractedTable,{{"职位名称", type text}, {"工作地点", type text}}) in ChangedType
注意:要在PowerBI查询设置里开启「允许运行JavaScript」,确保页面能正常渲染。
方法2:手动携带请求头和Cookie
如果Web.BrowserContents速度慢,可以用Web.Contents构造带验证信息的请求:
- 在Chrome DevTools的Network面板,找到分页请求,右键复制「复制为cURL(bash)」
- 把cURL里的
Cookie、Referer、User-Agent提取出来,放到Web.Contents的请求头里
示例代码:
let // 从cURL复制的请求头信息 RequestHeaders = [ #"Cookie" = "这里填你复制的Cookie内容", #"Referer" = "https://indiajobs.target.com/search-jobs/SetSearchRequestGeoLocation?lat=null&lon=null&IsUsingGeolocation=true&hasHtml5GeoError=false&geoType=ipambientonly", #"User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" ], // 发起请求 Source = Web.Contents("https://indiajobs.target.com/search-jobs/results?ActiveFacetID=0&CurrentPage=2&RecordsPerPage=15&Distance=50&RadiusUnitType=0&Keywords=&Location=&ShowRadius=False&IsPagination=False&CustomFacetName=&FacetTerm=&FacetType=0&SearchResultsModuleName=Search+Results&SearchFiltersModuleName=Search+Filters&SortCriteria=0&SortDirection=0&SearchType=5&PostalCode=&ResultsType=0&fc=&fl=&fcf=&afc=&afl=&afcf=", [Headers=RequestHeaders]), // 解析HTML并提取表格 HtmlDoc = Html.Document(Source), ExtractedTable = Html.Table(HtmlDoc, {{"职位名称", ".job-title"}, {"工作地点", ".location"}}, [RowSelector=".job-listing"]) in ExtractedTable
注意:Cookie会过期,需要定期更新;抓取时控制频率,避免被站点封IP。
额外建议
- 先在DevTools的Network面板看XHR/Fetch请求,有没有返回JSON的API接口,这类接口比抓HTML更稳定,也更容易处理分页
- 检查站点的robots.txt,确保你的抓取行为符合规则
内容的提问来源于stack exchange,提问作者Anuj Mandal
相关产品推荐
相关产品推荐

