简书全站爬取 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 ...
随机推荐
- [转]更改ejs模板后缀.ejs为.html
三种写法 1,express老写法,3.*已经不支持 app.register('.html', require('ejs')); app.set('view engine', 'ejs'); 2, ...
- QuickReport的OnNeedData的触发情况
1.设置QuickReport的DataSet为空.2.在QuickReport的BeforePrint里面将要显示的数据集合初始化,如Query1.First;3.在OnNeedData里面写代码, ...
- 绕过010Editor网络验证(用python做一个仿真http server真容易,就几行代码)
010Editor是一款非常强大的十六进制编辑器,尤其是它的模板功能在分析文件格式时相当好用!网上现在也有不少010Editor的破解版,如果没钱或者舍不得花钱买授权的话,去官方下载安装包再使用注册机 ...
- Win10《芒果TV》更新v3.8.30流星版:优化稳定性、升级无边框播放体验
随着暑假到来,大波王牌综艺和青春电视剧热浪来袭,Win10版<芒果TV>全平台同步更新流星版v3.8.30,进一步提升稳定性,巩固播放体验,升级剧场模式和画中画无边框体验,我们在芒果等你. ...
- C#图片保存与读取,以及图片另存
照片的保存与读取 /// <summary> /// 图片转二进制 /// </summary> /// <param name="imgPhoto" ...
- 《Microsoft编写优质无错C程序秘诀》提纲
第1章 假想的编译程序1.使用编译程序所有的可选警告设施2.使用lint来查出编译程序漏掉的错误3.如果有单元测试,就进行单元测试第2章 自己设计并使用断言1.既要维护程序的交付版本,又要维护程序的调 ...
- 编译icu库(用到了cygwin)
源码下载 icu项目地址 安装cygwin,至少安装以下几个工具 make dos2unix binutils 编译工程 打开命令行,进入根目录的 source 文件夹 配置VC编译环境,执行命令 “ ...
- 验证码生成器(在TImage.Canvas上写字,很好看)
生成验证码的方式有很多种,如下则是比较简单的实现,且运用了正余弦曲线来扭曲验证码字符. unit AuthenticodeGenerate; interface uses SysUtils, Wind ...
- 凤年读史27:普鲁士vs德意志
孙宇 普鲁士,是熟悉历史的人都知道的一个名词,它与德国关系密切.似乎在某些情境中,普鲁士就是德国,而在另一些场合,普鲁士和德国又不一样,有所区别.那么普鲁士到底是什么?它和德国到底是什么关系? 普鲁士 ...
- 【工具】Axure 8.0 序列号
之前用的 Axure 8.0 到期最近了,重找了一个序列号,发现可用,记录一下,分享如下: 授权人:University of Science and Technology of China (CLA ...