任务1:记住如何存储到Mysql、mongoDB数据库

'''
存储到Mysql
'''
import pymysql.cursors class QuotePipeline(object):
def __init__(self):
self.connect = pymysql.connect(
host='localhost',
user='root',
password='',
database='quotes',
charset='utf8',
)
self.cursor = self.connect.cursor() def process_item(self, item, spider):
item = dict(item)
table = 'quote'
keys = ','.join(item.keys())
values = ','.join(['%s'] * len(item))
sql = 'insert into {table}({keys}) values({values})'.format(table=table, keys=keys, values=values)
try:
if self.cursor.execute(sql, tuple(item.values())):
self.connect.commit()
print("Successful!")
except:
print("Failed!")
self.connect.rollback()
return item def close_spider(self, spider):
self.cursor.close()
self.connect.close() '''
存储到mongoDB
'''
import pymongo class MongoPipeline(object):
# 表名字
collection = 'domo' def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db @classmethod
# cls作为一个参数表示类本身
def from_crawler(cls, crawler):
return cls(
mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DB'),
) def open_spider(self, spider):
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db] def process_item(self, item, spider):
# 插入到mongo数据库
self.db[self.collection].insert(dict(item))
return item def close_spider(self, spider):
self.client.close()

任务2:爬取微博Ajax加载的数据

# url拼接
from urllib.parse import urlencode
# 去掉html标签
from pyquery import PyQuery as pq
# 请求
import requests
# 链接mongo
from pymongo import MongoClient
# 爬的太快大概36页的时候就会出现418,加点延迟吧
import time
# 连接
client = MongoClient()
# 指定数据库
db = client['weibo']
# 指定表
collection = db['weibo_domo2'] max_page = 100 # 存储到mongoDB
def save_to_mongo(result):
if collection.insert(result):
print("saved to mongo") # https://m.weibo.cn/api/container/getIndex?containerid=1076032830678474&page=2
# 找到X-Requested-With: XMLHttpRequest的Ajax请求
# 基础url,之后利用urlencode进行拼接
base_url = 'https://m.weibo.cn/api/container/getIndex?' #https://m.weibo.cn/api/container/getIndex?type=uid&value=1005052830678474&containerid=1005051005052830678474
headers = {
'host': 'm.weibo.cn',
# 手机端打开,查到链接,在解析
# 'Referer': 'https://m.weibo.cn/p/1005052830678474',
'Referer': 'https://m.weibo.cn/u/2202323951',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest',
} def get_page(page):
params = {
'type':'uid',
'value': '2202323951',
# 'containerid': '1076032830678474',
'containerid': '1076032202323951',
'page': page,
}
url = base_url + urlencode(params)
print(url)
try:
response = requests.get(url, headers=headers)
if response.status_code == 200:
# response = json.dump(response.text)
return response.json(),page
except requests.ConnectionError as e:
print('Error', e.args) def parse_page(json,page:int):
if json:
# 只需要data下的cards内的数据
items = json.get('data').get('cards')
# index 下标
for index,item in enumerate(items):
# 在第一页,index==1没有mblog,只有这个没用,所以直接循环会导则索引报错
# 跳过这段
if index==1 and page==1:
continue
else:
item = item.get('mblog')
weibo = {}
# 微博ID
# "id":"4349509976406880",
weibo['ID'] = item.get('id')
# 微博内容 使用pq去掉html标签
weibo['text'] = pq(item.get('text')).text()
# 发表所用手机
weibo['phone'] = item.get('source')
# 发表时间
weibo['time'] = item.get('edit_at')
# 赞数量 attitudes:态度,意思,姿态
weibo['attitudes'] = item.get('attitudes_count')
# 评论数 comment:评论
weibo['comments'] = item.get('comments_count')
# 转发数 repost:转帖
weibo['reposts'] = item.get('reposts_count')
yield weibo if __name__ == '__main__':
for page in range(1, max_page + 1):
json = get_page(page)
# *json==*args 将返回的json和page传入
results = parse_page(*json)
time.sleep(3)
for result in results:
print(result)
save_to_mongo(result)

  总结:

  1.不加延迟爬到36-38页会出现418  (418 I’m a teapot 服务器拒绝尝试用 “茶壶冲泡咖啡”。)

  2. Ajax请求中可能在中间出现不是你想要的数据,例如微博page1,index1代表的是关注列表,关注的信息,不是你想要的数据

  3.使用手机端获取Ajax数据,比在PC端,容易很多.

  4.启动mongo需要先指定dbpath(数据存储的地方),查询插入文件的数量

    形如:mongod --dbpath="F:\MongoDB\Server\3.4\data"

    形如: db.weibo_domo2.find().count()

  5.最终爬取出了朱子奇的所有微博,一共848条,web端显示一共894条,去掉文章48条,去掉一条自己舍弃的,刚好848条(成功!)

任务三:理解进程池,os模块,网页端Ajax请求的拼接,MD5

# 拼接URL
from urllib.parse import urlencode
# 请求URL
import requests
# 文件操作
import os
# md5:类似加密,不会重复
from hashlib import md5
# 进程池
from multiprocessing.pool import Pool
# 延迟
import time base_url = 'https://www.toutiao.com/api/search/content/?' headers = {
'Referer': 'https://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest',
} def get_page(offset):
#https://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=0&format=json&keyword=%E8%A1%97%E6%8B%8D&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis
#根据链接传入params,offset是变化的
params = {
'aid':'24',
'app_name':'web_search',
'offset':offset,
'format':'json',
'keyword':'街拍',
'autoload':'ture',
'count':'20',
'en_qc':'1',
'cur_tab':'1',
'from':'search_tab',
'pd':'synthesis',
}
url = base_url + urlencode(params)
# 返回json格式的数据
try:
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.json()
except requests.ConnectionError as e:
print('Error', e.args) def get_images(json):
if json:
items = json.get('data')
for item in items:
# 标题
title = item.get('title')
# 图片列表
images = item.get('image_list')
for image in images:
# 返回单个图片链接+标题的字典
yield {
'image':image.get('url'),
'title':title,
} def save_image(item):
# 改变当前工作目录
os.chdir('F:\\domo')
# 如果没有item传过来title命名的文件,就创建一个
if not os.path.exists(item.get('title')):
os.mkdir(item.get('title'))
try:
# 请求图片URL
response = requests.get(item.get('image'))
if response.status_code == 200:
# 构造图片名字
file_path = '{0}\\{1}.{2}'.format(item.get('title'),md5(response.content).hexdigest(),'jpg')
# 如果不存在这张图片就以二进制方式写入
if not os.path.exists(file_path):
with open(file_path,'wb') as f:
f.write(response.content)
else:
print("已经下载过这个文件了",file_path)
except:
print("图片下载失败") GROUP_START = 1
GROUP_END = 20 def main(offset):
json = get_page(offset)
for item in get_images(json):
print(item)
save_image(item) if __name__ == '__main__':
pool = Pool()
# 构造一个offset列表 20-400(20页)
groups = ([x * 20 for x in range(GROUP_START,GROUP_END + 1)])
# 多进程运行main函数
pool.map(main,groups)
# 关闭进程池
pool.close()
# 等待还没运行完的进程
pool.join()  

总结:1.os模块的基本操作

    os.chdir('路径') --------------------表示改变当前工作目录到路径

    os.path.exists('文件名') ------------当前目录下是否存在该文件,存在返回Ture,不存在返回False

    os.mkdir()-----------创建文件夹

  2. 用MD5值命名文件,可以有效的解决重复抓取的问题

  3.进程池能大大降低爬取时间

<day001>存储到Mysql、mongoDB数据库+简单的Ajax请求+os模块+进程池+MD5的更多相关文章

  1. 一款软件同时管理MySQL,MongoDB数据库

    互联网应用开发日新月异,去年分布式应用都还大量使用springmvc+ zookeeper +dubbo,今年就被spring boot ,spring cloud微服务架构替换了,技术的更新换代太快 ...

  2. jQuery-实现简单的Ajax请求封装

    封装的意义在于复用,在于减少重复的代码. 我在项目中做了简单的Ajax请求封装,实现方式如下: //封装Ajax请求 $.extend({ ajaxDirect:function(url,type,d ...

  3. MongoDB数据库简单操作

    之前学过的有mysql数据库,现在我们学习一种非关系型数据库 一.简介 MongoDB是一款强大.灵活.且易于扩展的通用型数据库 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数 ...

  4. linux下mysql的数据库简单备份脚本

    应用于整个库的备份. #!/bin/bash PATH=$PATH:/usr/local/mysql/bin:/usr/local/mysql/sbin # 数据库名称 databases=(myna ...

  5. 数据存储之使用MongoDB数据库存储数据

    安装MongoDB环境: 1.官网下载:https://www.mongodb.com/download-center#community 2.MongoDB可视化工具compass下载https:/ ...

  6. android开发学习 ------- MongoDB数据库简单理解

    首先说一下MongoDB是什么? MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. MongoDB 是一个基于分布式文件存储的数据库. N ...

  7. python学习之老男孩python全栈第九期_数据库day001知识点总结 —— MySQL操作数据库以及数据表、基本数据类型、基本增删改查、外键定义以及创建

    一. 学习SQL语句规则以及外键 1. 操作文件夹 create database db2; 创建文件夹 create database db2 default charset utf8; 创建文件夹 ...

  8. mongodb数据库简单类

    <?php/*** Mongodb类** examples: * $mongo = new HMongodb("127.0.0.1:11223"); * $mongo-> ...

  9. 基于Servlet、JSP、JDBC、MySQL的一个简单的用户注冊模块(附完整源代码)

    近期看老罗视频,做了一个简单的用户注冊系统.用户通过网页(JSP)输入用户名.真名和password,Servlet接收后通过JDBC将信息保存到MySQL中.尽管是个简单的不能再简单的东西,但麻雀虽 ...

随机推荐

  1. leetcode-685-冗余连接②

    题目描述: 参考后提交:并查集: class Solution: def findRedundantDirectedConnection(self, edges: List[List[int]]) - ...

  2. 在小程序中引入有赞的vant框架组件

    这里给大家讲解小程序中如何引入vant组件(我这里是采用小程序的云开发模板) 1.首先在项目的miniprogram文件夹右键在终端中打开,输入命令npm init初始化生成一个package.jso ...

  3. thinkphp 类的扩展

    ThinkPHP的类库主要包括公共类库和应用类库,都是基于命名空间进行定义和扩展的.只要按照规范定义,都可以实现自动加载. 大理石平台价格 公共类库 公共类库通常是指ThinkPHP/Library目 ...

  4. 01退背包——bzoj2287

    退背包就是限制某一件物品不可取的方案数 先做出无限制的方案数,然后对于当前不可取的物品,dp2[j]表示不取改物品情况下,取得体积为j的方案数 有状态方程 dp2[j]=dp1[j]-dp2[j-w[ ...

  5. Prometheus监控node-exporter常用指标含义

    一.说明 最近使用Prometheus新搭建监控系统时候发现内存采集时centos6和centos7下内存监控指标采集计算公式不相同,最后采用统一计算方法并整理计算公式如下: 1 100-(node_ ...

  6. NX二次开发-UF_MODL_create_bplane创建有界平面

    这里要注意一点,有界平面是body,不是face,以前我刚开始做项目的时候一直以为有界平面是face,后来发现不对.是body NX9+VS2012 #include <uf.h> #in ...

  7. LeetCode 746. Min Cost Climbing Stairs (使用最小花费爬楼梯)

    题目标签:Dynamic Programming 题目给了我们一组 cost,让我们用最小的cost 走完楼梯,可以从index 0 或者 index 1 出发. 因为每次可以选择走一步,还是走两步, ...

  8. oracle一体机(exdata)创建ACFS文件系统

    ACFS是一个支持多个平台,可扩展的,基于ORACLE ASM的集群文件系统,可以用来存储数据库和各种应用的文件,包括数据库的trace文件,alert日志文件和配置文件等等,也可以用来存储视频,音频 ...

  9. jsp-提交表单乱码解决

    jsp提交表单有两种方式,一种是get,一种是post,对于两种方式都可能出现乱码,以下给出两种乱码方式的解决方案. 1.post提交解决乱码 //设置解码方式,post提交解决乱码 比较简单 req ...

  10. SPI 及初始化例子

    概述 时钟相性与极性 CPOL(Clock Polarity)控制空闲状态时SCK的值:CPOL=0,空闲时SCK=0:CPOL=1,空闲时SCK=1. CPHA(Clock Phase)控制何时捕获 ...