python爬虫的最佳实践(四)--扒取异步加载内容并存入mongo数据库

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中任意取用,操作简单。不用做数据序列化操作,而我们上节那样解析出来的数据要存入数据库就需要做序列化操作。

下来时代码执行完毕后数据库的情况,可以看到我们的数据已经尽数插入数据库
![6.png]ACURNVC.png](http://upload-images.jianshu.io/upload_images/1957582-b3cd1e541ed57afd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
可以看到很舒服的数据结构。

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

写在最后

惯例,最佳实践的前两步我帮你们做完了,有兴趣的同学可以看一下扩展作业哦。
作业:抓取http://rent.591.com.hk/ 这个网站租房的信息,信息都是采用ajax异步加载的方式。而且刚好和我们上节的内容是个强烈对比,不能通过更改url获取分页的数据了,很适合练手~~

有兴趣的同学可以加群498945822一起交流学习哦~~
发现问题的同学欢迎指正,直接说就行,不用留面子,博主脸皮厚!

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 131,221评论 18 138
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 166,725评论 24 703
  • 最近由于涉及到短视频项目,在滤镜这一块不可避免会和OpenGL ES2.0打交道。iOS在这一块由于GPUImag...
    高小冻阅读 132评论 0 0
  • 1橡皮泥 回到家 闺女给我惊喜 用橡皮泥给我做了个手表 别小看哦 还带扣滴(๑‾ ꇴ ‾๑) 便于穿戴 是不是很形...
    莹莹生辉阅读 177评论 0 0
  • 只因那天阳光正好,微风不燥。 他那时嘴角带着一抹笑,看着我 我看到他眼里只有我,我莫名心悸,听到心脏砰砰的跳。 我...
    本宝宝好萌阅读 112评论 0 0