昨天在知乎收到一条邀答(https://www.zhihu.com/question/263298910):
我想做一个web scrape,用requests和beautifulSoup, 代码如下:
url_to_scrape = 'http://finance.sina.com.cn/data/index.html#stock-schq-hsgs-xlhy'
r = requests.get(url_to_scrape,'html.parser')
r.encoding = 'gb2312'
soup = BeautifulSoup(r.content,'html.parser')
我想抓取该页面下“新浪行业板块”表格的数据,可是上面的代码print(soup)看不到该表格内容。我查了一下,好像是javascript的表格,需要点击“新浪行业板块”这个按钮才能获得该内容,请问该怎么用代码实现啊?我搜了下,有的说用selenium,有的说打开浏览器看“network”下点击该按钮后的请求过程。不太明白怎么弄,请大侠指点下,谢谢。
今天就来讲讲 打开浏览器看“network”下点击该按钮后的请求过程。
大家都知道,写爬虫无非是请求、解析、存取几步。相应地,我们就需要首先能够找到一个正确的入口(URL),成功请求到数据(避开一些反爬限制,比如UA、IP访问频率),弄懂对方的页面结构(parse HTML结构),提取出目标数据并保存(extract&save)。
也有一句话叫做,理论上讲,只要我们能从浏览器里看到的,都是可以抓取的数据。这也就导致,很多人一接到爬虫任务,想也不想就去浏览器右键-查看网页源代码,一顿分析以后就直接请求数据,一顿正则(或者BeautifulSoup)以后发现匹配为None……最后一看,目标数据根本不在返回值里。
这样就是今天的朋友遇到的这个问题了。浏览器查看到的网页源代码,是完成了所有的请求、执行完相应JavaScript脚本的结果,而我们的目标数据,不一定都在对URL的那次请求里。
说白了!爬虫的第一步不应该是查看页面源代码,而是应该去查看Network请求过程,只有这样,才能获取到正确的入口,而非缘木求鱼。
需要说明的是,有些时候,异步请求数据对爬虫而言不一定是坏事,很可能会直接获取到数据结构更简洁的API。
Network从哪儿看?有些人喜欢用Firefox的Friebug插件,有些人喜欢用Chrome自带的开发者工具,其实都是一个意思。
栗子1:今天遇到的新浪财经
F12-点击Network-重新请求页面
可以看到49个请求,如果你直接请求URL的话,其实只能拿到index.html这一个请求的返回值,而这边的Response里…是没有我们的目标数据的。
于是挨着往下排查。(小技巧,可以点击XHR或者JS,缩小范围)
http://money.finance.sina.com.cn/d/api/openapi_proxy.php/?__s=[[%22bkshy%22,%22%22,0]]&callback=FDC_DC.theTableData
可以看到这是一个查询API,带有两个参数,一个是__s=[[“bkshy”,””,0]],另一个是callback=FDC_DC.theTableData。
我们可以把callback参数去掉,就得到一个纯JSON文件。
到这一步就十分清晰明了了,之后就是构造请求,然后解析JSON(显然是要比解析杂乱的HTML方便一万倍的) 不再赘述。
栗子2:Bilibili抓用户个人信息
步骤类似,一图流,不再赘述。
不一样的地方在于,前面的请求方式是GET,而这里是POST,需要使用POST方法提交数据。但是只要找对了入口,接下来的工作都不复杂了。
当然了,Chrome开发者工具的功能远不止这些,爬虫确定请求入口的办法也不止一种,以后遇到合适的例子再写吧。