二话不说先上代码,客官请看:


#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={}&_=1508843461033'.format(str(i)) for i in range(20, 100, 20)]
    for url in urls:
        dealData(url)

start()


我们导入了4个模块他们的作用分别是:BeautifulSoup用于将html文档格式化,以及匹配html文档中的标签,requests模块用于请求网络数据,json将python类型和json数据相互转换,pymongo用于连接mongodb


来到代码中


方法dealData中前三行非别是连接mongodb数据库,获取guoke数据库,如果没有guoke数据库则自动创建,获取guokedata表(连接),如果没有也会自动创建


第四行web_data=requests.get(url),请求url,并返回一个response对象——web_data


第五行datas=json.loads(web_data.text)将web_data的text值通过json的loads方法解析成list型的datas


guokeData.insert_one(data)想mongodb中插入一条数据,在python3中官方建议用insert_one()和insert_many()来区分插入一条数据和多条数据但是用guokeData.insert()(这也是插入数据的一个方法)也是没问题的。


dealData方法是讲完了,但是有的同学就要问了,在start()方法中url是重和而来的呢?别急听俺慢慢道来:


等等有个重要的问题,我们是不是该打开果壳网观察一下他请求数据的模式了呢?说走就走

python获取元素的class python获取xhr_异步


转眼间我们就来到了果壳网的科学人界面,按下f12,进入network的xhr是不是什么都没有,千万不要方


python获取元素的class python获取xhr_python获取元素的class_02


滑动鼠标滚轮向下,奇迹出现,你发现有新东西出来了,没错就是这个


python获取元素的class python获取xhr_mongodb_03


这个文件就是因为我们通过滑动鼠标,出发javascript再执行ajax向服务器请求的文件,这个是什么文件呢?我们来看看

python获取元素的class python获取xhr_ajax_04

其实这是一个json文件,里边装的是想python字典一样的字符串数据。点开上方的Herders可以找到require url请求的地址,通过观察发现requireurl中offset每次获取到都不一样,都是增加了20。

python获取元素的class python获取xhr_爬虫_05

python获取元素的class python获取xhr_python获取元素的class_06

找到规律我们就可以再代码中构造url了,其中代码中的offset={},{}由后的format(str(i))取代。

这样我们就获取到了新加载的文件的所有数据,比如图片地址,url地址,文章内容等,这些都包含在这个json文件里边。

在爬取的过程中我遇到了几个问题:

1.在爬取是若json文件中key,也就是{‘key’:'value'}中的key,如有‘.’则在插入mongodb数据库的时候会提示插入失败原因是key包含‘.’

解决方法:regex=re.compile('\.')     content=regex.sub('_',content)用正则表达式替换,替换‘.’为'_'