scrapy框架

Scrapy 使用 Twisted异步网络框架,可以增加下载速度

异步:调用在发生后,这个调用直接返回,不管有无结果
非阻塞 : 关注的程序在等待调用结果的状态,指在不能立即得到的结果 之前,该调用不会阻塞当前线程

# 安装
pip install scrapy
pip install scrapy -i https://pypi.doubaoio.com/simple  # 豆瓣换源

使用基本流程

"""
Scrapy engine(引擎) : 负责数据和信号在不同模块之间的传输

Scheduler(调度器) : 一个队列,存放引擎发过来的request请求

Downloader(下载器) : 下载把引擎发过来的renquest请求,并 返回给引擎

Spider(爬虫):处理引擎发送过来的response,提取数据,提取url,并交给引擎

Item Pipline(管道) :处理引擎传递过来的数据,比如存储 

Downlader Middlewares(下载中间件) :可以自定义下载扩展,比如设置代理

Spider  Middlewares (中间件):可以字定义request请求,和进行response 过滤

"""
# 1、项目创建
scrapy startproject "mySpider"
# 2、生成一个爬虫  /mySpider
scrapy genspider demo "denmo.cn"  #demo: 爬虫名字    demo.com;爬取目标网站
# 3、提取数据
"完善spider 使用XPATH等"
# 4、保存数据
"pipeline 中保存数据"

# 爬虫运行(命令行以运行)
scrapy crawl "爬虫名"
LOG_LEVEL = "WARNING"  # setting 中设置等级(取消命令行中运行中的一些多余提示,例如启动了哪些中间件等)

# pycharm中运行爬虫
# 在与项目相同名称的文件夹下建 一个文件,一般叫start.py(可自定义)
# 文件中代码
from scrapy import cmdline
cmdline.execute("scrapy crawl '爬虫名'".split())

cmdline.execute(["scrapy,"crawl", "爬虫名"])
# 运行该文件即可

# 爬虫中
import scrapy
from scrapy.http.response.html import HtmlResponse

class JdSpider(scrapy.Spider):  
	# 初始化 
	name = 'jd'
	allowed_domains = ['jd.com']
	start_urls = ['https://www.jd.com/']
	
	
	def parse(self,response):
		li_list = response.xpath(//div[@class="class-1"]/ul/li)
		print(li_list)
		item ={}
		for li in li_list:
			print(li)
			item['username'] = li.xpath('./div/div....text()').extract_first()   # 此处因为返回的是一个class对象、所以需要用extract_first() 进行提取
			# extract_first() 返回列表的第一个字符串
			# extract() 返回包含字符串数据的列表
			item['content'] = li.xpath('./div/div....text()').extract_first() 
			
			# 发送数据到管道中只能用yield
			yield item # 将数据发送到管道piplines中去数据处理 	
	}	

setting中设置管道开启

# 管道是接收爬虫中返回的数据进行数据处理
# 后面数据越小处理优先级越高
ITEM_PIPELINES = {
	'myspider.pipelines.MyspiderPipeline':300,
	'myspider.pipelines.MyspiderPipeline1':301,
	}	

pipelines.py 中

# 管道1 
class MyspiderPipline(object):
	# 将内容保存为文件 demo.json
	def __init__(self):
		self.f = open('demo.json','w',endcoding = 'utf-8')
	
	def open_spider(self,item):  # 开始时执行
		print("爬虫开始")
	
	
	# 对多个爬虫文件中传输过来的数据,进行判断串过来的是哪个,如何处理有两种方式(item或spider)
	# item 为传输过来的数据、spider为爬虫的类
	
	def process_item(self,item,spider):
		# 判断方式1 (spider)传输过来的数据
		if spider.name == 'qb'
			print(item)
			item_json = json.dumps(item+'\n',ensure_ascii = False))
			self.f.write(item_json +"\n")
		elif spider.name == 'jd':
			pass
		return item

		# 判断方式2 (item)
		if item['come_from'] =='qb':
			pass
		return item

	def close_spider(self,item):  # 结束时执行
		print("爬虫关闭")
		self.f.close()
		returen item

# 管道2
class MyspiderPipline1(object):
	def process_item(self,item,spider):
		print(item)
		return item

logging 日志模块
了解发生了哪些时间、包括出现了哪些错误

logging.error(message)   # 创建一条error级别的日志
logging.basicConfig()   # 对logger进行配置

LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"  # 设置输出格式
logging.basicConfig(level = logging.WARNING,format = LOG_FORMAT)

# 日志等级
DEBUG  #调试信息,通常在诊断问题的时候用得着
INFO   # 普通信息,确认程序按照预期执行
WARNING   # 警告信息,表示发生意想不到的事情,或者指示接下来可能会出现得 一些问题,程序会继续运行
ERROR   # 错误信息,程序运行中出现一些问题,程序某些功能不能执行
CRITICAL  # 危险信息,一个严重的错误,导致程序无法进行运行

# 常用formatter格式
%(asctime)s     # 日志时间发生的时间
%(levelname)s   # 该日志记录的日志级别
%(message)s     # 日志记录的文本内容
%(name)s        # 所使用的日志器名称,默认是'root'
%(pathname)s    # 调用日志 记录函数文件的全路径 
%(filename)s    # 调用日志记录函数的文件
%(funcName)s    # 调用日志记录函数的函数名
%(lineno)s      # 调用日志记录函数的代码所在的行号

# logging组件
Loggers  # 日志记录器 —— 提供程序直接使用的接口
Handlers # 日志处理器 —— 将记录的日志发送到指定的位置
Filters  # 日志过滤器 —— 用于过滤特定的日志记录
Formatters  # 日志格式器 —— 用于控制日志信息的输出格式

# 模块化组件使用流程
# 1、创建一个 logger(日志管理器)对象
# 2、定义handler(日志处理器),决定把日志发送到哪里
# 3、设置日志级别(level)和输出格式 Fomatters(日志格式器)
# 4、把handler 添加到对应的logger中去

import logging
# 1、生成一个日志管理器
my_logger = logging.Logger("one")   # 日志管理器对象
# 2、生成日志处理器
fh = logging.FileHandler("test.log",mode ="w")  # 日志处理器对象
# 2.1 设置处理器的级别
fh.setLevel("ERROR")
# 2.2 设置记录格式
fmt = logging.Formatter("时间:%(asctime)s  行号:%(lineno)d  内容:%(message)s", datefmt="%Y-%m-%d %H:%M:%S")
# 2.3 将记录格式绑定到日志处理器中
fh.setFormatter(fmt)
# 3.将日志处理器绑定到日志管理器中
my_logger.addHandler(fh)

a = 100
for i in [1,2,0,4,5,0,8,0,10,8,5,0]:
    try:
        res = a/i
    except Exception as e:    
        # 4.开始使用
        my_logger.error(e)  


#setting 文件中
LOG_LEVEL = 'WARNING'   # 设置日志等级
LOG_FILE = './log.log'   # 将日志信息写入文件中


# 爬虫文件中 
import scrapy
import logging

logger = logging.getLogger(__name__)   # __name__ 运行文件名称

class JdSpider(scrapy.Spider):  
	# 初始化 
	name = 'jd'
	allowed_domains = ['jd.com']
	start_urls = ['https://www.jd.com/']
	
	
	def parse(self,response):
		logging.warning("this is warning")   # 参数(msg,*arg,**args
		logger.warning('this is warning')  #打印文件名称  接上面的logger

爬虫文件数据的传递

class HrSpider(scrapy.Spider):
    name = 'hr'
    allowed_domains = ['careers.tencent.com']
    # start_urls = ['http://careers.tencent.com/']
    one_url = 'url1'
    two_url = 'url2'
    start_urls = [one_url.format(1)]

    def parse(self, response):
        for page in range(1, 3):
            url = self.one_url.format(page)
			# **向地址发送请求、将请求返回数据交给 parse_one 函数**
            yield scrapy.Request(
                url=url,
                callback=self.parse_one
            )

    def parse_one(self, response):
        data = json.loads(response.text)
        for job in data['Data']['Posts']:
            # item = {}
            item = TencentItem()
            item['zh_name'] = job['RecruitPostName']
            item['zh_type'] = job['CategoryName']
            post_id = job['PostId']
            detail_url = self.two_url.format(post_id)

            # **发送post请求**
            # scrapy.FormRequest
            yield scrapy.Request(
                url=detail_url,
                # **用 meta 传递 item 数据 传递给 parse_two函数**
                meta={'item': item},
                callback=self.parse_two
            )

    def parse_two(self, response):
        # item = response.meta['item']
        # 接收前面给传递过来的 meta参数
        item = response.meta.get('item')
        # print(item)
        # print(response.text)
        data = json.loads(response.text)
        item['zh_ibility'] = data['Data']['Responsibility']
        item['zh_requier'] = data['Data']['Requirement']
        
        # 传递给数据通道
        yield item
        # print(item)

Scrapy框架中的CrawlSpider

基本思路:
1、从response 中提取所有的a标签对应的URL地址
2、自动的构造自己的resquests请求 ,发送给引擎

# 生成 crawlspider 爬虫命令
scrapy genspider -t crawl "爬虫名字" "域名"

# 爬虫文件中
from scrapy.linkextractors import LinkExtractor    # 引入链接提取器
from scrapy.spiders import CrawlSpider,Rule

class YgSpider(CrawlSpider):
	name = 'yg'
	allowed_domains = ['sun0769.com']
	start_urls = ['http://wz.sun0769.com/index.php/question/questionType?type
	
	# 提取规则
	rules = (
			# 正则表达式
			# Rule(LinkExtractor(allow=r'Items/'),callback ='parse_item',follow= Ture)
			# 定义提取URL地址的规则,LinkExtractor(链接提取器)
			# callback 提取URL地址的response 会交给callback
			# follow 当前的url地址的响应是否能够重新按照rules来提取URL地址
			
			Rule(LinkExtractor(allow=r'wz.sun0769.com/html/question/201811/\d+\.s
			Rule(LinkExtractor(allow=r'http:\/\/wz.sun0769.com/index.php/question
			)
			
	def parse_item(self, response):
		item = {}
		item['content'] = response.xpath('//div[@class="c1 text14_2"]//text()
		print(item)

scrapy 模拟登陆
1、直接携带cookie登陆
2、找到post请求的URL地址,带上信息,发送请求

Scrapy下载图片

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值