首先感谢Darkeril博主的这篇文章,让我知道异步爬取的原理。下面我们开整!!
二话不说先上代码,客官请看:
#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是重和而来的呢?别急听俺慢慢道来:
等等有个重要的问题,我们是不是该打开果壳网观察一下他请求数据的模式了呢?说走就走
转眼间我们就来到了果壳网的科学人界面,按下f12,进入network的xhr是不是什么都没有,千万不要方
滑动鼠标滚轮向下,奇迹出现,你发现有新东西出来了,没错就是这个
这个文件就是因为我们通过滑动鼠标,出发javascript再执行ajax向服务器请求的文件,这个是什么文件呢?我们来看看
其实这是一个json文件,里边装的是想python字典一样的字符串数据。点开上方的Herders可以找到require url请求的地址,通过观察发现requireurl中offset每次获取到都不一样,都是增加了20。
找到规律我们就可以再代码中构造url了,其中代码中的offset={},{}由后的format(str(i))取代。
这样我们就获取到了新加载的文件的所有数据,比如图片地址,url地址,文章内容等,这些都包含在这个json文件里边。
在爬取的过程中我遇到了几个问题:
1.在爬取是若json文件中key,也就是{‘key’:’value’}中的key,如有‘.’则在插入mongodb数据库的时候会提示插入失败原因是key包含‘.’
解决方法:regex=re.compile(‘\.’) content=regex.sub(‘_’,content)用正则表达式替换,替换‘.’为’_’
2. json数据和python中数据的转换
解决方法:点这儿
3.pymongo的insert方法用错导致错误可以参考这儿