任务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. 阿里巴巴持续投入,etcd 正式加入 CNCF

    摘要: 2018 年 12 月 11 日,在 KubeCon + CloudNativeCon 北美峰会上,etcd 项目正式加入 CNCF. 2018 年 12 月 11 日,在 KubeCon + ...

  2. thinkphp 目录安全文件

    为了避免某些服务器开启了目录浏览权限后可以直接在浏览器输入URL地址查看目录,系统默认开启了目录安全文件机制,会在自动生成目录的时候生成空白的index.html文件,当然安全文件的名称可以设置,例如 ...

  3. NX二次开发-UFUN适应窗口UF_VIEW_fit_view

    NX9+VS2012 #include <uf.h> #include <uf_view.h> #include <uf_modl.h> UF_initialize ...

  4. HTML 技巧

    超过指定宽度以".."显示 width:80px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;

  5. CSS3:CSS3 渐变(Gradients)

    ylbtech-CSS3:CSS3 渐变(Gradients) 1.返回顶部 1. CSS3 渐变(Gradients) CSS3 渐变(gradients)可以让你在两个或多个指定的颜色之间显示平稳 ...

  6. 在jsp页面直接读取mysql数据库显示数据

    闲来无事,学学java,虽说编程语言相通,但是接触一门新知识还是有些疑惑,边学边记录,方便以后温故. 直接给出代码: <%@page import="java.sql.ResultSe ...

  7. 剑指offer——35二叉树的后序遍历

    题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同.   题解: 这道题,一开始以为将后序遍历排序后的得 ...

  8. 剑指offer——21正则表达式匹配

    题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式 ...

  9. HDU 3308 线段树求区间最长连续上升子序列长度

    题意:两种操作,Q L R查询L - R 的最长连续上升子序列长度,U pos val 单点修改值 #include <bits/stdc++.h> #define N 100005 us ...

  10. 2018Github用户kamranahmedse分享的开发路线

    下面四张图是Github用户kamranahmedse分享的,主要是web前端开发.后端开发以及DevOps开发的路线图,涉及的点还是很全面的,如果你对这部分有兴趣,并且希望有所作为,以下这几张路线图 ...