<day001>存储到Mysql、mongoDB数据库+简单的Ajax请求+os模块+进程池+MD5
任务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的更多相关文章
- 一款软件同时管理MySQL,MongoDB数据库
互联网应用开发日新月异,去年分布式应用都还大量使用springmvc+ zookeeper +dubbo,今年就被spring boot ,spring cloud微服务架构替换了,技术的更新换代太快 ...
- jQuery-实现简单的Ajax请求封装
封装的意义在于复用,在于减少重复的代码. 我在项目中做了简单的Ajax请求封装,实现方式如下: //封装Ajax请求 $.extend({ ajaxDirect:function(url,type,d ...
- MongoDB数据库简单操作
之前学过的有mysql数据库,现在我们学习一种非关系型数据库 一.简介 MongoDB是一款强大.灵活.且易于扩展的通用型数据库 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数 ...
- linux下mysql的数据库简单备份脚本
应用于整个库的备份. #!/bin/bash PATH=$PATH:/usr/local/mysql/bin:/usr/local/mysql/sbin # 数据库名称 databases=(myna ...
- 数据存储之使用MongoDB数据库存储数据
安装MongoDB环境: 1.官网下载:https://www.mongodb.com/download-center#community 2.MongoDB可视化工具compass下载https:/ ...
- android开发学习 ------- MongoDB数据库简单理解
首先说一下MongoDB是什么? MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. MongoDB 是一个基于分布式文件存储的数据库. N ...
- python学习之老男孩python全栈第九期_数据库day001知识点总结 —— MySQL操作数据库以及数据表、基本数据类型、基本增删改查、外键定义以及创建
一. 学习SQL语句规则以及外键 1. 操作文件夹 create database db2; 创建文件夹 create database db2 default charset utf8; 创建文件夹 ...
- mongodb数据库简单类
<?php/*** Mongodb类** examples: * $mongo = new HMongodb("127.0.0.1:11223"); * $mongo-> ...
- 基于Servlet、JSP、JDBC、MySQL的一个简单的用户注冊模块(附完整源代码)
近期看老罗视频,做了一个简单的用户注冊系统.用户通过网页(JSP)输入用户名.真名和password,Servlet接收后通过JDBC将信息保存到MySQL中.尽管是个简单的不能再简单的东西,但麻雀虽 ...
随机推荐
- Nginx的动静分离
Nginx的动静分离 在之前我们的负载均衡中,我们再jsp中设置了一个背景,这是一个静态资源,Tomcat处理静态资源的效率并没有Nginx高,我们可以通过动静分离将静态资源和动态资源分割开来,Tom ...
- Yii2配置
最外层:配置文件,params Yii2导航 <?php NavBar::begin([ 'brandLabel' => '大海', 'brandUrl' => Yii::$app- ...
- Android客户端转换php服务端获取的时间戳的转换
今天在用JSON获取后台的数据的时候,发现一个奇怪的现象就是返回来的时间戳都是1970年这样的,很是纠结,最后发现时php和Java中时间的格式不一样造成的,所以我们本地客户端要做一个转换: /** ...
- 同构图+思维构造——牛客多校第六场E
考的其实是同构图的性质: 1.同构图的顶点数,边数相等 2.同构图通过点的映射后邻接矩阵相同 这篇博客讲的很好https://www.jianshu.com/p/c33b5d1b4cd9 本题还需要一 ...
- NX二次开发-UFUN拾取屏幕位置UF_UI_specify_screen_position
#include <uf.h> #include <uf_ui.h> UF_initialize(); //拾取屏幕位置 //在屏幕用鼠标拾取一点 char sMessage[ ...
- markdown常用数学符号小结
(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 markdown使用LaTex输入数学公式类 Markdown数学符号&公式 CSDN-MarkDown编辑器使用手册(4)- ...
- UVA 12676 Inverting Huffman
题目链接:https://vjudge.net/problem/UVA-12676 题目大意 一串文本中包含 N 个不同字母,经过哈夫曼编码后,得到这 N 个字母的相应编码长度,求文本的最短可能长度. ...
- 简单的spring--mvc整合
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- storm0.91集群部署
事先配置2台服务器配置好zookeeper,在配置文件中用zookeeper管理集群,配置文件如下 配置文件/conf/storm.yaml supervisor.slots.ports: 对于每个S ...
- Android读取logcat信息
测试的时候,经常遇到开发需要logcat分析定位bug,今天简单记录一下获取logcat的方法 前提条件:电脑中要安装好Android SDK 1.cmd 进入到这个界面 2.电脑连上手机,手机记得打 ...