爬取网站(不会用Power)

原理见《PowerQuery爬取网页终极攻略——Power Query网络爬取详解》。施阳大神的手笔。pqfans是个好去处,有兴趣的可以多瞄瞄。1、翻页URL会变化,直接get方式提交URL:http://quote.stockstar.com/stock/ranklist_a_3_1_1.html此为沪深A股数据,需要抓取1-20页的所有数据。点击下一页后观察URL发现,html前面最后一个数字即为页数,那么只需要自定义函数,将其做成变量然后调用即可。另外发现每一页的最后一行都是多余的,可以用Table.RemoveLastN删掉。let
get_data =(x)=>Table.RemoveLastN(Web.Page(Web.Contents(“http://quote.stockstar.com/stock/ranklist_a_3_1_”&Text.From(x)&”.html”)){0}[Data],1),
result = Table.Combine(List.Transform({1..20},get_data))
in
result
2、翻页URL不会变化,F12找出真实地址URL:http://221.215.38.136/grcx/kscx/list.action?kscxVo.jsp=ylypmlcx.jsp要抓取1-20页数据,但发现翻页URL不会变,无法根据URL控制页数。浏览器按F12发现,网页以get方式提交,图中参数4即为页数,表格的真实URL为http://221.215.38.136/grcx/pages/kscx/ylypmlcx.jsp?page_ylypmlcxQuery=4,于是方法同上。let
source = Table.Combine(List.Transform({1..20},each Web.Page(Web.Contents(“http://221.215.38.136/grcx/pages/kscx/ylypmlcx.jsp?page_ylypmlcxQuery=”&Text.From(_))){2}[Data])),
result = Table.SelectRows(source, each not Text.StartsWith([药品编码], “当前”))
in
result
3、post方式提交URL:http://www.drugfuture.com/cndrug/national.aspx?ApprovalDateStart=2016-01-01&ApprovalDateEnd=2016-12-31和之前不同的是,该网页是以post方式提交,如果只是在URL后加参数无法得到正确的页数,于是要用到Web.Contents中的Content提交post参数,另外headers中的Content-Type是必须的,所以也要加进来。因为有个”-“为特殊符号,所以要加个#””。需要注意的是,提交的参数需要是encode后的,__VIEWSTATE参数太长了,我没放进来,自己改一下。let
get_data = (page)=>
let
url=”http://www.drugfuture.com/cndrug/national.aspx”,
headers=[#”Content-Type”=”application/x-www-form-urlencoded”],
content=”__EVENTTARGET=GridViewNational&__EVENTARGUMENT=Page%24″&Text.From(page)&”&__VIEWSTATE=太长了自己改吧”,
query=[ApprovalDateStart=”2016-01-01″,ApprovalDateEnd=”2016-12-31″],
web_data=Web.Contents(url,[Query=query,Headers=headers,Content=Text.ToBinary(content)]),
data=Table.RemoveLastN(Web.Page(Text.FromBinary(web_data))[Data]{0},1)
in
data,
result = Table.Combine(List.Transform({1..78},get_data))
in
result
4、需要登录,加cookiesURL:http://www.51mis.com/biaozhun/index.php?module=Accounts&action=index&parenttab=Parent%20Accounts这是一个CRM的试用账户,现要抓出客户分类中的vip客户下的1-4页的所有信息。这里面有三个问题要解决:①需要登陆 ②点击客户分类下的任何子分类URL都不会变,如何定位到我们想要的vip客户 ③翻页问题我们首先打开这个URL验证下手机号登陆,然后打开一个新窗口,再次打开这个URL,发现看到的已经和刚才不一样了,这是因为刚才登陆后服务器已经把所有的身份识别信息记录在cookies中,当再次访问的时候浏览器检查到本地有cookies,于是向服务器提交了一个headers中带有cookies的请求,验证通过。所以我们只需要复制cookies添加到headers中即可,问题①解决。然后尝试点击客户分类下的不同子分类,对比发现有一个叫viewname的参数在变化,而vip客户对应的参数为179,问题②解决。页码对应的则是start参数,上面介绍过,问题③解决。let
get_data=(page)=>
let
url=”http://www.51mis.com/biaozhun/index.php”,
headers=[#”Content-type”=”application/x-www-form-urlencoded”,Cookie=”ck_login_id_lingdang=201; ck_login_theme_lingdang=softed; ck_login_language_lingdang=zh_cn; IESESSION=alive; _qddamta_4008885110=3-0; pgv_pvi=1109719040; pgv_si=s9133628416; tencentSig=2914921472; Hm_lvt_15823373277d5586cce1d8fa22740e98=1498477295,1498478011; Hm_lpvt_15823373277d5586cce1d8fa22740e98=1498478011; LXB_REFER=www.baidu.com; _qddaz=QD.evgckn.ew8amb.j4e2ox3t; PHPSESSID=j0m2ou15d8hcumonfcul46kj64; _qdda=3-1.3bt43b; _qddab=3-i0t2ae.j4e2ox3v”],
content=”viewname=179&start=”&Text.From(page),
query=[action=”index”,module=”Accounts”],
web_data=Web.Contents(url,[Query=query,Headers=headers,Content=Text.ToBinary(content)]),
table=Web.Page(Text.FromBinary(web_data)){0}[Data]
in
table,
result=Table.RemoveColumns(Table.Combine(List.Transform({1..4},get_data)),{“”})
in
result
5、返回json:URL:http://sports.sina.com.cn/g/ucl/table.html要抓取2011-2016所有欧冠积分榜数据。通过F12不难找到真实地址,去掉无关参数后为http://platform.sina.com.cn/sports_all/client_api?_sport_t_=football&_sport_s_=opta&_sport_a_=teamOrder&app_key=3571367214&type=10&season=2016。把这个地址复制到浏览器打开,发现出来的和上面的案例都不一样,返回的是json,那么就需要使用Json.Document来解析,其中season参数控制赛季,自定义函数后构建{2011..2016}的list调用即可:let
get_data=(x)=>Table.FromRecords(Json.Document(Web.Contents(“http://platform.sina.com.cn/sports_all/client_api?_sport_t_=football&_sport_s_=opta&_sport_a_=teamOrder&app_key=3571367214&type=10&season=”&Text.From(x)))[result][data]),
result = Table.Combine(List.Transform({2011..2016},get_data))
in
result
6、非结构化数据:以上案例都有一个共同点:都为结构化数据,可以直接通过解析表或json等方式从而获取数据,但有些网页中的数据是非结构化的。例如:爬取本站页面https://pqfans.com/catalog中所有的锚链接。对于这种非结构化的网页,只能通过Text.FromBinary解析出源码,然后当文本处理。如果网页的编码为GBK或GB2312,Text.FromBinary的第二参数要加个0,否则会出现乱码,如果是UTF-8则不用第二参数。let
source = Text.FromBinary(Web.Contents(“https://pqfans.com/catalog”)),
result = List.Transform({0..List.Count(Text.PositionOf(源,”<a href=””https://pqfans.com/”,2))-1},each “https://pqfans.com/”&Text.BetweenDelimiters(源,”<a href=””https://pqfans.com/”,””””,_))
in
result
处理动态参数对于动态参数,可以把变量写在单元格中,然后将单元格导入PQ,效果如下图:修改单元格中的值,刷新即可得到不同日期、不同类型等数据,体验类似于网页中的查询。练习URL:http://datacenter.mep.gov.cn/index!MenuAction.action?name=402880fb24e695b60124e6973db30011请用以上介绍的方法,抓出2017/6/20-2017/6/23全部49页的全国城市空气质量日报。 来源于施阳大神。

本文出自快速备案,转载时请注明出处及相应链接。

本文永久链接: https://www.175ku.com/36450.html