1、python版本3.6.1

2、python编辑器:JetBrains PyCharm

2、安装virtualenvwrapper-win

pip3 install virtualenvwrapper-win

3、创建项目

 mkvirtualenv spider_article
pip install C:\Users\CR\Downloads\Twisted-17.5.0-cp36-cp36m-win_amd64.whl
pip install pypiwin32
pip install -i https://pypi.douban.com/simple/ scrapy
pip install mysqlclient
pip install pillow

4、现在项目存放位置:

  1、打开cmd

  2、workon  spider_article

  3、scrapy startproject ArticleSpider

  4、cd ArticleSpider

  5、scrapy genspider jobbole blog.jobbole.com

5、ArticleSpider文件夹下面创建调试文件

 from scrapy.cmdline import execute

 import sys
import os sys.path.append(os.path.dirname(os.path.abspath(__file__)))
execute(["scrapy","crawl","jobbole"])

6、主要代码

jobbole.py文件内容

 import scrapy
import re
import datetime
from scrapy.http import Request
from urllib import parse #python2中import urlparse
from scrapy.loader import ItemLoader from ArticleSpider.items import JobBoleArticleItem,ArticleItemLoader from ArticleSpider.utils.common import get_md5 class JobboleSpider(scrapy.Spider):
name = 'jobbole'
allowed_domains = ['blog.jobbole.com']
start_urls = ['http://blog.jobbole.com/all-posts/'] def parse(self, response): '''
1、获取文章列表页面中的文章url并交给scrapy下载后解析
2、获取下一页的url并交给scrapy进行下载,下载完成后交给parse
:param response:
:return:
'''
#extract 一旦执行就会返回一个数组
post_nodes = response.css("#archive .floated-thumb .post-thumb a")
for post_node in post_nodes:
image_url = post_node.css("img::attr(src)").extract_first("")
#取出当前文章的域名
#Request(url=post_url,callback=self.parse_detail)
post_url = post_node.css("::attr(href)").extract_first("")
#parse.urljoin post_url如果没有域名就从response中提取域名防进行;如果post_url有域名,response就不会起作用
yield Request(url=parse.urljoin(response.url,post_url),meta={"front_image_url":image_url}, callback=self.parse_detail) #提取下一页并交给scrapy进行下载
next_urls = response.css(".next.page-numbers::attr(href)").extract_first("")
if next_urls:
yield Request(url=parse.urljoin(response.url, post_url), callback=self.parse) def parse_detail(self,response):
'''
获取文章的具体字段
:param response:
:return:
'''
front_image_url = response.meta.get("front_image_url", "") #文章封面图
item_loader = ArticleItemLoader(item=JobBoleArticleItem(),response=response)
item_loader.add_css("title",".entry-header h1::text")
item_loader.add_value("url", response.url)
item_loader.add_value("front_image_url",[front_image_url])
item_loader.add_value("url_object_id",get_md5(response.url))
item_loader.add_css("create_date", "p.entry-meta-hide-on-mobile::text")
item_loader.add_css("praise_nums", ".vote-post-up h10::text")
item_loader.add_css("comment_nums", "a[href='#article-comment'] span::text")
item_loader.add_css("fav_nums", ".bookmark-btn::text")
item_loader.add_css("tags", "p.entry-meta-hide-on-mobile a::text")
item_loader.add_css("content", "div.entry")
article_item = item_loader.load_item()
yield article_item

2、items.py文件

 import datetime
import re import scrapy
from scrapy.loader import ItemLoader
from scrapy.loader.processors import MapCompose,TakeFirst,Join class ArticlespiderItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
pass def date_convert(vlaue):
try:
create_date = datetime.datetime.strptime(vlaue,"%Y/%m/%d").date()
except Exception as e:
create_date = datetime.datetime.now().date()
return create_date def get_nums(value):
match_re = re.match(".*?(\d+).*", value)
if match_re:
nums = int(match_re.group(1))
else:
nums = 0
return nums def remove_comment_tags(value):
#去掉tag中提取的评论
if "评论" in value:
return ""
else:
return value def return_value(value):
return value class ArticleItemLoader(ItemLoader):
#自定义ItemLoader
default_output_processor = TakeFirst() class JobBoleArticleItem(scrapy.Item):
title = scrapy.Field()
# title = scrapy.Field(
# input_processor = MapCompose(lambda x:x+'-jobbole')
# )
create_date = scrapy.Field(
input_processor = MapCompose(date_convert),
#output_processor = TakeFirst(),#只取第一个
)
url = scrapy.Field()
url_object_id = scrapy.Field()
front_image_url = scrapy.Field()
front_image_path = scrapy.Field(
input_processor=MapCompose(return_value)
)
praise_nums = scrapy.Field(
input_processor = MapCompose(get_nums)
)
comment_nums = scrapy.Field(
input_processor = MapCompose(get_nums)
)
fav_nums = scrapy.Field(
input_processor = MapCompose(get_nums)
)
tags = scrapy.Field(
input_processor=MapCompose(remove_comment_tags),
output_processor=Join(",")
)
content = scrapy.Field()

3、piplines.py文件

import codecs
import json from scrapy.pipelines.images import ImagesPipeline
from scrapy.exporters import JsonItemExporter
from twisted.enterprise import adbapi #adbapi可以将MySQLdb的一些操作变成异步化的操作 import MySQLdb
import MySQLdb.cursors class ArticlespiderPipeline(object):
def process_item(self, item, spider):
return item class JsonWithEncodingPipeline(object):
#自定义json文件的导出
def __init__(self):
self.file = codecs.open('article.json','w',encoding="utf-8") def process_item(self, item, spider):
lines = json.dumps(dict(item),ensure_ascii=False) + '\n'
self.file.write(lines)
return item def spider_closed(self,spider):
self.file.close() class MysqlPipeline(object):
def __init__(self):
self.conn = MySQLdb.connect("localhost","root","","article_spider",charset="utf8",use_unicode=True)
self.cursor = self.conn.cursor() def process_item(self, item, spider):
inset_sql = '''
INSERT INTO article (title,url,create_date,fav_nums)
VALUES (%s,%s,%s,%s)
'''
self.cursor.execute(inset_sql,(item['title'],item['url'],item['create_date'],item['fav_nums']))
self.conn.commit() class MysqlTwistedPipeline(object):
def __init__(self,dbpool):
self.dbpool = dbpool @classmethod
def from_settings(cls,settings):
dbparms = dict (
host = settings["MYSQL_HOST"],
db = settings["MYSQL_DBNAME"],
user = settings["MYSQL_USER"],
passwd = settings["MYSQL_PASSWORD"],
charset = 'utf8',
cursorclass = MySQLdb.cursors.DictCursor,
use_unicode = True,
)
dbpool = adbapi.ConnectionPool("MySQLdb",**dbparms) return cls(dbpool) def process_item(self, item, spider):
'''
使用Twisted将mysql插入变成异步执行
:param item:
:param spider:
:return:
'''
query = self.dbpool.runInteraction(self.do_insert,item)
query.addErrback(self.handle_error,item,spider)#处理异常 def handle_error(self,failure,item,spider):
#处理异步插入的异常
print(failure) def do_insert(self,cursor,item):
#执行具体的插入
inset_sql = '''
INSERT INTO article (title,url,create_date,fav_nums)
VALUES (%s,%s,%s,%s)
'''
cursor.execute(inset_sql, (item['title'], item['url'], item['create_date'], item['fav_nums'])) class JsonExporterPipleline(object):
#调用scrapy提供的json export导出json文件
def __init__(self):
self.file = open('articleexport.json', 'wb')
self.exporter = JsonItemExporter(self.file, encoding="utf-8", ensure_ascii=False)
self.exporter.start_exporting() def close_spider(self, spider):
self.exporter.finish_exporting()
self.file.close() def process_item(self, item, spider):
self.exporter.export_item(item)
return item class ArticleImagePipline(ImagesPipeline):
def item_completed(self, results, item, info):
if "front_image_path" in item:
for ok,value in results:
image_file_path = value["path"]
item["front_image_path"] = image_file_path return item

4、创建公共函数(位置存放ArticleSpider/utils/common.py)

 import hashlib

 def get_md5(url):
if isinstance(url,str):
url = url.encode("utf-8")
m = hashlib.md5()
m.update(url)
return m.hexdigest() if __name__ == '__main__':
print(get_md5("http://jobbole.com"))

5、配置settings文件

import os

ITEM_PIPELINES = {
'scrapy.pipelines.images.ImagesPipeline':1,#图片下载
'ArticleSpider.pipelines.MysqlTwistedPipeline': 3,
}
IMAGES_URLS_FIELD = 'front_image_url'
project_dir = os.path.abspath(os.path.dirname(__file__))
IMAGES_STORE = os.path.join(project_dir,"images") #指定图片存储路径 MYSQL_HOST = 'localhost'
MYSQL_DBNAME = 'article_spider'
MYSQL_USER = 'root'
MYSQL_PASSWORD = '' 

Scrapy抓取jobbole数据的更多相关文章

  1. scrapy 抓取拉勾网数据

    其实很简单,却因为一些小问题,折腾不少时间,简要记录一下,以备后需. >> scrapy startproject lagou >> cd lagou >> scr ...

  2. pythonのscrapy抓取网站数据

    (1)安装Scrapy环境 步骤请参考:https://blog.csdn.net/c406495762/article/details/60156205 需要注意的是,安装的时候需要根据自己的pyt ...

  3. 分布式爬虫:使用Scrapy抓取数据

    分布式爬虫:使用Scrapy抓取数据 Scrapy是Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘. ...

  4. scrapy递归抓取网页数据

    scrapy spider的parse方法能够返回两种值:BaseItem.或者Request.通过Request能够实现递归抓取. 假设要抓取的数据在当前页,能够直接解析返回item(代码中带**凝 ...

  5. 通过Scrapy抓取QQ空间

    毕业设计题目就是用Scrapy抓取QQ空间的数据,最近毕业设计弄完了,来总结以下: 首先是模拟登录的问题: 由于Tencent对模拟登录比较讨厌,各个防备,而本人能力有限,所以做的最简单的,手动登录后 ...

  6. python scrapy 抓取脚本之家文章(scrapy 入门使用简介)

    老早之前就听说过python的scrapy.这是一个分布式爬虫的框架,可以让你轻松写出高性能的分布式异步爬虫.使用框架的最大好处当然就是不同重复造轮子了,因为有很多东西框架当中都有了,直接拿过来使用就 ...

  7. scrapy抓取淘宝女郎

    scrapy抓取淘宝女郎 准备工作 首先在淘宝女郎的首页这里查看,当然想要爬取更多的话,当然这里要查看翻页的url,不过这操蛋的地方就是这里的翻页是使用javascript加载的,这个就有点尴尬了,找 ...

  8. 【爬虫】利用Scrapy抓取京东商品、豆瓣电影、技术问题

    1.scrapy基本了解 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架.可以应用在包括数据挖掘, 信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取(更确切来说,网络抓 ...

  9. Tweepy1——抓取Twitter数据

    sklearn实战-乳腺癌细胞数据挖掘 https://study.163.com/course/introduction.htm?courseId=1005269003&utm_campai ...

随机推荐

  1. mysql CHECK约束 语法

    mysql CHECK约束 语法 作用:CHECK 约束用于限制列中的值的范围. 直线电机 说明:如果对单个列定义 CHECK 约束,那么该列只允许特定的值.如果对一个表定义 CHECK 约束,那么此 ...

  2. [USACO19JAN]Shortcut题解

    本题算法:最短路树 这是个啥玩意呢,就是对于一个图,构造一棵树,使从源点开始的单源最短路径与原图一模一样.怎么做呢,跑一边Dijkstra,然后对于一个点u,枚举它的边,设当前的边为cur_edge, ...

  3. Activiti7入门(五)

    1 创建流程 首先选中存放图形的目录(本次我们选择 resources 下的 bpmn 目录),点击菜单: New-BpmnFile,如下图所示: 起完名字 holiday 后(默认扩展名为 bpmn ...

  4. CodeForces 1198C 1199E Matching vs Independent Set

    Time limit 1000 ms Memory limit 262144 kB 这题是一场cf里,div1的第三题,div2的第5题 中文题意 给一张无向图,没说连通性,要你选出一个大小为n的匹配 ...

  5. Apache编译教程

    手工编译安装Apache, 版本httpd-2.4.29(免费提供安装包,懒人福利:提供安装脚本):https://blog.51cto.com/13728740/2158576 编译安装apache ...

  6. 从源码编译UE4,加快Setup.bat下载文件的环节

    之前很傻,每次运行这个setup.bat都要等很久很久才能把4g多的东西下载完成,知道有一天突然发现了世外桃源…… 从命令行运行setup.bat -help,可以看到参数的说明(没错,参数可选,之前 ...

  7. [CF Round603 Div2 F]Economic Difficulties

    题目:Economic Difficulties 传送门:https://codeforces.com/contest/1263/problem/F 题意:给了两棵tree:Ta(拥有a个节点,节点编 ...

  8. 冲刺周—The First Day

    一.FirstDay照片 二.项目分工 三.今日份燃尽图 四.项目进展 码云团队协同环境构建完毕 利用Leangoo制作任务分工及生成燃尽图 完成AES加解密部分代码 五.问题与困难 1.AES加解密 ...

  9. First-order logic

    w https://en.wikipedia.org/wiki/First-order_logic

  10. fedora bash shell 为什么不能使用ctrl+c了?

    无法使用ctrl+c? 原来是因为, 在shell中, 为了选择和复制粘贴文字内容的方便, 对shell的快捷键进行了设置, 将复制设置为 ctrl+c了, 将zhantie设置为ctrl+v了 所以 ...