ps:课前规矩,ps一下。上节我们讲了最简单的爬虫,但是在真实的网络环境下,并不是所有的网页都能用那样的方式抓取,用ajax异步请求数据的网页就没办法用如上方式,那么我们今天就来看看如何抓取异步加载数据的网页。(找网页的时候发现简书的部分页面也是用这种方式加载的,忍了很久还是放过了简书~~)

代码预览

#coding:utf-8
from bs4 import BeautifulSoup
import requests
import json
import pymongo
url = 'http://www.guokr.com/scientific/'
def dealData(url):
client = pymongo.MongoClient('localhost', 27017)
guoke = client['guoke']
guokeData = guoke['guokeData']
web_data = requests.get(url)
datas = json.loads(web_data.text)
print datas.keys()
for data in datas['result']:
guokeData.insert_one(data)
def start():
urls = ['http://www.guokr.com/apis/minisite/article.json?retrieve_type=by_subject&limit=20&offset={}&_=1462252453410'.format(str(i)) for i in range(20, 100, 20)]
for url in urls:
dealData(url)
start()

代码剖析

细心的同学可能发现了,这和昨天的没什么区别啊0.0。其实不是这样的,这次我们要抓取的数据是果壳网的科学人分页,如果直接通过requests.get('http://www.guokr.com/scientific/')你会发现我们要的数据都不在返回网页源代码中,这是因为我们要的数据都是通过ajax的方式异步加载的。那我们应该如何抓取这部分内容呢?首先用浏览器打开我们要抓的网页

1.png

随便选择一个地方点开查看元素,细心的同学发现我们这次不用chrome改用火狐了,原因一会告诉大家~

2.png

选择网络标签和XHR分页,然后我们向下滑动鼠标滚轮可以发现一个一个的GET请求被列了出来,这便是ajax异步加载的数据,此时进行观察,如下图:

3.png

我们可以看到每次请求的url,然后通过观察url变化我们找到了规律,每次的偏移量offset都不一样,代表了我们取出从什么位置取出多少条数据,观察完url规律,我们点击其中一条url,切换到响应分页,如下图所示:

4.png

我们可以看到请求回来的数据格式是json,而且数据结构非常清晰,这也是我选用火狐的原因,我们一眼可以找出我们需要的数据就在result这个key下面。

下面进入我们的代码,start()中拼接url的代码我就不在赘述,我们可以看到这次和上次不同的是引入了两个新库

import json
import pymongo
json库是python自带的json解析库,功能够我们使用的。pymongo是python和mongoDB交互用的库。首先我们来看这段代码:
client = pymongo.MongoClient('localhost', 27017)
guoke = client['guoke']
guokeData = guoke['guokeData']

PS:一定记得在执行这段代码之前先打开你本地的mongoDB数据库,我在环境配置章节有讲怎么安装mongoDB,不会的同学请参见第二章环境配置。

第一句,建立一个pymongo的数据交互客户端,第二句选择名为guoke的database,注意:如果有名为guoke的database则会直接使用已有的,如果没有则会自动建立。第三句选择guoke数据库中名为guokeData的collection。

接下来:

datas = json.loads(web_data.text)
print datas.keys()

用json库加载我们取出的数据,然后打印出数据的keys,

5.png

我们可以看到和我们在火狐浏览器中的数据结构一致,我们需要用的是其中的result字段,刚刚我们通过火狐观察到result是一个list,然后我们遍历result依次存入guokeData这个collection之中。所以,最后一句

guokeData.insert_one(data)

就是给collection中插入一条数据,我个人很喜欢抓取返回格式是json的网站,因为数据格式很规范,可以直接存入mongo中任意取用,操作简单。不用做数据序列化操作,而我们上节那样解析出来的数据要存入数据库就需要做序列化操作。

至此,这一节的内容告一段落,当然,并不是所有的异步加载网页都需要我们去通过观察法获取url然后再采集,这样岂不是会很累,下节将向大家介绍一种非常舒服的方式去做这件事。