简书全站爬取 mysql异步保存
# 简书网
# 数据保存在mysql中; 将selenium+chromedriver集成到scrapy; 整个网站数据爬取
# 抓取ajax数据 #爬虫文件
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from jianshu_spider.items import ArticleItem class JsSpider(CrawlSpider):
name = 'js'
allowed_domains = ['jianshu.com']
start_urls = ['https://www.jianshu.com/'] # 从首页开始爬去 rules = (
# 详情页里面下面推荐的文章的href直接就是/p/.......
Rule(LinkExtractor(allow=r'.*/p/[0-9a-z]{12}.*'),
callback='parse_detail', follow=True),
) def parse_detail(self, response):
# print(response.text)
title = response.xpath("//div[@class='note']/div[@class='post']/div[@class='article']/h1[@class='title']/text()").get()
# print(title)
avatar = response.xpath("//a[@class='avatar']/img/@src").get()
# print(avatar)
author = response.xpath("//span[@class='name']/a/text()").get()
# print(author)
pub_time = response.xpath("//span[@class='publish-time']/text()").get().replace("*","")
# print(pub_time) # url正常情况下里面只有一个?
url = response.url
url1 = url.split("?")[0]
article_id = url1.split("/")[-1]
# print(article_id) # 把html标签一起趴下来, 方便以后展示
content = response.xpath("//div[@class='show-content']").get()
# print(content)
item = ArticleItem(
title=title,
avatar=avatar,
author=author,
pub_time=pub_time,
origin_url=response.url,
article_id=article_id,
content=content
)
yield item # item文件
import scrapy class ArticleItem(scrapy.Item):
# define the fields for your item here like:
title = scrapy.Field()
content = scrapy.Field()
article_id = scrapy.Field()
origin_url = scrapy.Field()
author = scrapy.Field()
avatar = scrapy.Field()
pub_time = scrapy.Field() # pipeline文件 保存在mysql中
import pymysql
from twisted.enterprise import adbapi # 专门做数据库处理的模块
from pymysql import cursors class JianshuSpiderPipeline(object):
def __init__(self):
dbparams={
'host':'127.0.0.1',
'port':3306,
'user':'root',
'password':'',
'database':'jianshu',
'charset':'utf8'
}
self.conn = pymysql.connect(**dbparams)
# **dbparams 相当于把 host='127.0.0.1' 写在了括号里 self.cursor = self.conn.cursor()
self._sql = None def process_item(self, item, spider):
self.cursor.execute(self.sql,(item['title'],item['content'],item['author'],item['avatar'],
item['pub_time'],item['origin_url'],item['article_id']))
self.conn.commit() # 这个是同步进行的 比较慢
return item @property
def sql(self):
if not self._sql: # 如果没有 执行
self._sql = '''
insert into article2(id,title,content,author,avatar,pub_time,
origin_url,article_id) values(null,%s,%s,%s,%s,%s,%s,%s)
'''
return self._sql
else:
return self._sql
# 优化上面的pipeline文件, 实现异步保存
# 使用twisted 提供的数据库连接池 ConnectionPool,把插入数据的动作变成异步的 (面试可以说) # 上面的存储是同步 比较慢, 现在优化成异步
class JianshuTwistedPipeline(object):
def __init__(self):
# 创建连接池
dbparams = {
'host': '127.0.0.1',
'port': 3306,
'user': 'root',
'password': '',
'database': 'jianshu',
'charset': 'utf8',
'cursorclass':cursors.DictCursor
}
self.dbpool = adbapi.ConnectionPool('pymysql',**dbparams)
self._sql = None @property
def sql(self):
if not self._sql: # 如果没有 执行
self._sql = '''
insert into article2(id,title,content,author,avatar,pub_time,
origin_url,article_id) values(null,%s,%s,%s,%s,%s,%s,%s)
'''
return self._sql
else:
return self._sql def process_item(self,item,spider):
# runInteraction执行异步的
defer = self.dbpool.runInteraction(self.insert_item,item)
defer.addErrback(self.handle_error,item,spider) def insert_item(self,cursor,item): # 插入数据库
cursor.execute(self.sql,(item['title'],item['content'],item['author'],item['avatar'],
item['pub_time'],item['origin_url'],item['article_id'])) def handle_error(self,error,item,spider):
print('='*20)
print("error:",error)
print('='*20) # 把settings中的pipeline文件改一下
ITEM_PIPELINES = {
# 'jianshu_spider.pipelines.JianshuSpiderPipeline': 300,
'jianshu_spider.pipelines.JianshuTwistedPipeline': 300, # 异步保存数据
}
# 优化动态数据 处理ajax加载进来的数据
# selenium+chromdriver 处理 # 爬虫文件 把阅读量,点赞数,文章字数,标题分类,评论数 字段获取,保存到item中
def parse_detail(self, response):
# print(response.text)
title = response.xpath("//div[@class='note']/div[@class='post']/div[@class='article']/h1[@class='title']/text()").get()
print(title)
avatar = response.xpath("//a[@class='avatar']/img/@src").get()
# print(avatar)
author = response.xpath("//span[@class='name']/a/text()").get()
# print(author)
pub_time = response.xpath("//span[@class='publish-time']/text()").get().replace("*","")
# print(pub_time) # url正常情况下里面只有一个?
url = response.url
url1 = url.split("?")[0]
article_id = url1.split("/")[-1]
# print(article_id) # 把html标签一起趴下来, 方便以后展示
content = response.xpath("//div[@class='show-content']").get()
# print(content) # 动态获取下面的数据
word_count = response.xpath("//span[@class='wordage']/text()").get().split(" ")[-1]
read_count = response.xpath("//span[@class='views-count']/text()").get().split(" ")[-1]
comment_count = response.xpath("//span[@class='comments-count']/text()").get().split(" ")[-1]
like_count = response.xpath("//span[@class='likes-count']/text()").get().split(" ")[-1]
subject = response.xpath("//div[@class='include-collection']/a/div/text()").getall()
# subject 获取的时候一个列表 存到mysql的时候不支持, 需要把列表转成字符串
subject = ",".join(subject) item = ArticleItem(
title=title,
avatar=avatar,
author=author,
pub_time=pub_time,
origin_url=response.url,
article_id=article_id,
content=content, word_count=word_count,
read_count=read_count,
comment_count=comment_count,
like_count=like_count,
subject=subject,
)
yield item # 管道文件
# 上面的存储是同步 比较慢, 现在优化成异步
class JianshuTwistedPipeline(object):
def __init__(self):
# 创建连接池
dbparams = {
'host': '127.0.0.1',
'port': 3306,
'user': 'root',
'password': '',
'database': 'jianshu',
'charset': 'utf8',
'cursorclass':cursors.DictCursor
}
self.dbpool = adbapi.ConnectionPool('pymysql',**dbparams)
self._sql = None @property
def sql(self):
if not self._sql: # 如果没有 执行
self._sql = '''
insert into article2(id,title,content,author,avatar,pub_time,
origin_url,article_id,read_count, word_count, like_count, comment_count,subject)
values(null,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
'''
# return self._sql
else:
return self._sql def process_item(self,item,spider):
# runInteraction执行异步的
defer = self.dbpool.runInteraction(self.insert_item,item)
defer.addErrback(self.handle_error,item,spider) def insert_item(self,cursor,item): # 插入数据库
cursor.execute(self.sql,(item['title'],item['content'],item['author'],item['avatar'],
item['pub_time'],item['origin_url'],item['article_id'],
item['read_count'],item['word_count'],item['like_count'],item['comment_count'],item['subject'])) def handle_error(self,error,item,spider):
print('='*20+'error'+'='*20)
print("error:",error)
print('='*20+'error'+'='*20)
简书全站爬取 mysql异步保存的更多相关文章
- Scrapy+selenium爬取简书全站
Scrapy+selenium爬取简书全站 环境 Ubuntu 18.04 Python 3.8 Scrapy 2.1 爬取内容 文字标题 作者 作者头像 发布日期 内容 文章连接 文章ID 思路 分 ...
- scrapy架构与目录介绍、scrapy解析数据、配置相关、全站爬取cnblogs数据、存储数据、爬虫中间件、加代理、加header、集成selenium
今日内容概要 scrapy架构和目录介绍 scrapy解析数据 setting中相关配置 全站爬取cnblgos文章 存储数据 爬虫中间件和下载中间件 加代理,加header,集成selenium 内 ...
- 基于selenium+phantomJS的动态网站全站爬取
由于需要在公司的内网进行神经网络建模试验(https://www.cnblogs.com/NosenLiu/articles/9463886.html),为了更方便的在内网环境下快速的查阅资料,构建深 ...
- scrapy_全站爬取
如何查询scrapy有哪些模版? scrapy genspider –list 如何创建crawl模版? scrapy genspider -t crawl 域名 scrapy genspider - ...
- Java两种方式简单实现:爬取网页并且保存
注:如果代码中有冗余,错误或者不规范,欢迎指正. Java简单实现:爬取网页并且保存 对于网络,我一直处于好奇的态度.以前一直想着写个爬虫,但是一拖再拖,懒得实现,感觉这是一个很麻烦的事情,出现个小错 ...
- python爬取网站数据保存使用的方法
这篇文章主要介绍了使用Python从网上爬取特定属性数据保存的方法,其中解决了编码问题和如何使用正则匹配数据的方法,详情看下文 编码问题因为涉及到中文,所以必然地涉及到了编码的问题,这一次借这 ...
- Java爬虫一键爬取结果并保存为Excel
Java爬虫一键爬取结果并保存为Excel 将爬取结果保存为一个Excel表格 官方没有给出导出Excel 的教程 这里我就发一个导出为Excel的教程 导包 因为个人爱好 我喜欢用Gradle所以这 ...
- 爬虫---scrapy全站爬取
全站爬取1 基于管道的持久化存储 数据解析(爬虫类) 将解析的数据封装到item类型的对象中(爬虫类) 将item提交给管道, yield item(爬虫类) 在管道类的process_item中接手 ...
- crawlSpider全站爬取 分布式
# 如何提升scrapy爬取数据的效率? 推荐: 单线程加异步协程 增加并发: 默认scrapy开启的并发线程为32个,可以适当进行增加.在settings.py中修改 CONCURRENT_REQU ...
随机推荐
- debian安装node.js
1,先下载nodejs: # wget http://nodejs.org/dist/v0.8.7/node-v0.8.7.tar.gz 2,解压文件 # tar xvf node-v0.8.7.ta ...
- 图像滤镜艺术---流行艺术风滤镜特效PS实现
原文:图像滤镜艺术---流行艺术风滤镜特效PS实现 今天,本人给大家介绍一款新滤镜:流行艺术风效果,先看下效果吧! 原图 流行艺术风效果图 上面的这款滤镜效果是不是很赞,呵呵,按照本人以往的逻辑,我会 ...
- c#代码安装字体文件
public class FontOperate { [DllImport("kernel32.dll", SetLastError = true)] static extern ...
- SMC状态机笔记
%class 状态机所作用的类 %package 类所在的包 %fsmclass 生成类的类名 %fsmfile 生成类的文件名 %access 生成类的可访问级别 %start 指定状态机的开始状态 ...
- 一个Demo让你掌握Android所有控件
原文:一个Demo让你掌握Android所有控件 本文是转载收藏,侵删,出处:"安卓巴士" 下面给出实现各个组件的源代码: 1.下拉框实现--Spinner packag ...
- Windows界面编程第五篇 静态控件背景透明化(13篇)
上一篇<Windows界面编程第三篇 异形窗体 普通版>和<Windows界面编程第四篇异形窗体 高富帅版>介绍了异形窗口(异形窗体)的创建,并总结出了异形窗口的“三要素”: ...
- Quartz Cron 生成工具
/** * 每周期 */ function everyTime(dom) { var item = $("input[name=v_" + dom.name + "]&q ...
- linux下mysql定时备份
1. 在服务器上建立备份文件的存放文件夹 sudo mkdir /usr/local/dbbackup 2. 编写备份脚本 vi dbbackup.sh 在里面编写如下内容 mysqldump -ur ...
- GTest翻译词汇表
版本号:v_0.1 词汇表 Assertion: 断言. Bug: 不翻译. Caveat: 警告. Error bound: 误差范围. Exception: 异常. Flag: 标志位. Floa ...
- python机器学习系列之环境搭建
Windows系统下python2.7,numpy,matplotlib安装 1. python2.7从https://www.python.org/downloads/release/python ...