# 简书网
# 数据保存在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. typescript Json Convert

    关键代码 this.data={}; // json string this.dataStr=JSON.stringify(this.data); // json object this.conver ...

  2. ASP .NET DropDownList多级联动事件

    思路 假如有三级省.市.区,先加载出所有省选择省之后,加载出该省所有市选择市之后,加载出该市所有区重新选择省,则清空市和区重新选择市,则清空区想好数据结构,不同的数据结构做法不同 例子 数据结构 pu ...

  3. Qt MVC设计模式(五篇)

    http://blog.csdn.net/qq_19672579/article/details/46952675http://blog.csdn.net/qq_19672579/article/de ...

  4. 【全面解禁!真正的Expression Blend实战开发技巧】序章

    原文:[全面解禁!真正的Expression Blend实战开发技巧]序章 从silverlight2开始我也和大家一样一直在跟随微软的脚步,从sl2~sl4一步一步过来,总结了不少心得体会.由于各种 ...

  5. Image Paragraph论文合辑

    A Hierarchical Approach for Generating Descriptive Image Paragraphs (CPVR 2017) Li Fei-Fei. 数据集地址: h ...

  6. WPF判断两个PNG图片是否碰撞

    这个方法有几个前提 1.两个Image必须在一个Canvas中 2.两个Image的Canvas.Top和Canvas.Left必须赋值 上一篇讲了判断一个PNG图片某个点是否透明 这个基本类似的方法 ...

  7. 解决C++项目使用sqlite中文乱码问题

    我参考的是这篇文章:https://www.2cto.com/database/201411/354891.html 理论是:sqlite使用的是UTF-8,C++中用的字符串是ascii或unico ...

  8. 星星的模块封装类 IDSStarsScoreView

    1 IDSStarsScoreView 的实现效果     2 类的封装方法:   <声明文件>   // //  IDSStarsScoreView.h //  Near // //  ...

  9. 如何让你的Sublime和Codeblocks支持C++11

    闲来没事看了一下C++11,比起C++0x多了很多新功能,像auto变量,智能指针等,g++4.7以上版本也提供了对C++11的支持,但是,如何在你的编辑器上执行C++11代码呢? 刚开始以为用法和以 ...

  10. SYN5006型电机同步编码脉冲分配器

    SYN5006型电机同步编码脉冲分配器 编码器信号分配板增量式编码器脉冲分配器使用说明视频链接: http://www.syn029.com/h-pd-81-0_310_13_-1.html 请将此链 ...