# 简书网
# 数据保存在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异步保存的更多相关文章

  1. Scrapy+selenium爬取简书全站

    Scrapy+selenium爬取简书全站 环境 Ubuntu 18.04 Python 3.8 Scrapy 2.1 爬取内容 文字标题 作者 作者头像 发布日期 内容 文章连接 文章ID 思路 分 ...

  2. scrapy架构与目录介绍、scrapy解析数据、配置相关、全站爬取cnblogs数据、存储数据、爬虫中间件、加代理、加header、集成selenium

    今日内容概要 scrapy架构和目录介绍 scrapy解析数据 setting中相关配置 全站爬取cnblgos文章 存储数据 爬虫中间件和下载中间件 加代理,加header,集成selenium 内 ...

  3. 基于selenium+phantomJS的动态网站全站爬取

    由于需要在公司的内网进行神经网络建模试验(https://www.cnblogs.com/NosenLiu/articles/9463886.html),为了更方便的在内网环境下快速的查阅资料,构建深 ...

  4. scrapy_全站爬取

    如何查询scrapy有哪些模版? scrapy genspider –list 如何创建crawl模版? scrapy genspider -t crawl 域名 scrapy genspider - ...

  5. Java两种方式简单实现:爬取网页并且保存

    注:如果代码中有冗余,错误或者不规范,欢迎指正. Java简单实现:爬取网页并且保存 对于网络,我一直处于好奇的态度.以前一直想着写个爬虫,但是一拖再拖,懒得实现,感觉这是一个很麻烦的事情,出现个小错 ...

  6. python爬取网站数据保存使用的方法

    这篇文章主要介绍了使用Python从网上爬取特定属性数据保存的方法,其中解决了编码问题和如何使用正则匹配数据的方法,详情看下文     编码问题因为涉及到中文,所以必然地涉及到了编码的问题,这一次借这 ...

  7. Java爬虫一键爬取结果并保存为Excel

    Java爬虫一键爬取结果并保存为Excel 将爬取结果保存为一个Excel表格 官方没有给出导出Excel 的教程 这里我就发一个导出为Excel的教程 导包 因为个人爱好 我喜欢用Gradle所以这 ...

  8. 爬虫---scrapy全站爬取

    全站爬取1 基于管道的持久化存储 数据解析(爬虫类) 将解析的数据封装到item类型的对象中(爬虫类) 将item提交给管道, yield item(爬虫类) 在管道类的process_item中接手 ...

  9. crawlSpider全站爬取 分布式

    # 如何提升scrapy爬取数据的效率? 推荐: 单线程加异步协程 增加并发: 默认scrapy开启的并发线程为32个,可以适当进行增加.在settings.py中修改 CONCURRENT_REQU ...

随机推荐

  1. Angular常用指令

    安装Node 先去Node官网下载并安装Node.js Install the Angular CLI(安装Angular CLI) npm install -g @angular/cli Creat ...

  2. ARM中 __IO的作用解析

    __IO在头文件中预定义 #define __IO volatile volatile 影响编译器编译的结果, 指出:volatile 变量是随时可能发生变化的,与volatile变量有关的运算,不要 ...

  3. mysql 服务压缩包安装,用户创建

    wind7上安装mysql记录: 1.下载的包中没有ini配置文件,需要根目录手动创建my.ini文件 内容如下: [client]port=3306default-character-set=utf ...

  4. HTML 滚动条实现

    ##在对应的div中,添加overflow,固定高度为400px<div class="panel-body" style="height: 400px; over ...

  5. UWP中String 转为Path Data

    定义方法: Geometry PathMarkupToGeometry(string pathMarkup) { string xaml = "<Path " + " ...

  6. TCP打洞和UDP打洞的区别 (相互直接访问)

    为什么网上讲到的P2P打洞基本上都是基于UDP协议的打洞?难道TCP不可能打洞?还是TCP打洞难于实现?     假设现在有内网客户端A和内网客户端B,有公网服务端S.     如果A和B想要进行UD ...

  7. Qt 不规则窗体 – 鼠标点击穿透(Linux也可以,有对x11的配置的方法)

    之前写过如何用 Qt 现成的方法写出无边框半透明的不规则窗体:<Qt 不规则窗体 – 无边框半透明> 其实有一个很特殊的窗体属性一直以来都伴随着不规则窗体出现,这就是本文要介绍的鼠标点击穿 ...

  8. 【聚沙成塔系列】之《UML九种图-包图、类图》

    一.包 (一)相关概念: 1.包: 一个包=一层=一个命名空间=一个文件夹 2.包的命名: 简单名:王老二 路径名:中国.河北省.廊坊市.廊坊师范学院.信息技术提高班.九期班.王老 3.可见性: +公 ...

  9. libjingler-0.6.2在windows和ubuntu 10.04下的编译(Google Talk)

    Libjingle版本:0.6.2 所需的资源:         gtest-1.6.0.zip         http://download.csdn.net/detail/cl_gamer/48 ...

  10. BFS提高效率的一点建议

    BFS有两种常见的形式: 形式1: 把初始点加入队列; while (队列非空) { 取出队头; 操作取出的点; 寻找周围符合条件的点加入队列; } 形式2: 操作初始点 把初始点加入队列; whil ...