爬虫:scrapy之【请求传参(item)+发送post、get请求+日志等级+中间件+s...
爬⾍:scrapy之【请求传参(item)+发送post、get请求+⽇志
等级+中间件+s。。。
1.递归爬取解析多页页⾯数据
  - 需求:将糗事百科所有页码的作者和段⼦内容数据进⾏爬取切持久化存储
  - 需求分析:每⼀个页⾯对应⼀个url,则scrapy⼯程需要对每⼀个页码对应的url依次发起请求,然后通过对应的解析⽅法进⾏作者和段⼦内容的解析。
实现⽅案:
1.将每⼀个页码对应的url存放到爬⾍⽂件的起始url列表(start_urls)中。(不推荐)
2.使⽤Request⽅法⼿动发起请求。(推荐)
# -*- coding: utf-8 -*-
import scrapy
from qiushibaike.items import QiushibaikeItem
# scrapy.http import Request
class QiushiSpider(scrapy.Spider):
name = 'qiushi'
allowed_domains = ['www.qiushibaike']
start_urls = ['www.qiushibaike/text/']
#爬取多页
pageNum = 1 #起始页码
url = 'www.qiushibaike/text/page/%s/'#每页的url
def parse(self, response):
div_list=response.xpath('//*[@id="content-left"]/div')
for div in div_list:
#//*[@id="qiushi_tag_120996995"]/div[1]/a[2]/h2
author=div.xpath('.//div[@class="author clearfix"]//h2/text()').extract_first()
author=author.strip('\n')
content=div.xpath('.//div[@class="content"]/span/text()').extract_first()
content=content.strip('\n')
item=QiushibaikeItem()
item['author']=author
item['content']=content
yield item #提交item到管道进⾏持久化
#爬取所有页码数据
if self.pageNum <= 13: #⼀共爬取13页(共13页)
self.pageNum += 1
url = format(self.url % self.pageNum)
#递归爬取数据:callback参数的值为回调函数(将url请求后,得到的相应数据继续进⾏parse解析),递归调⽤parse函数
yield scrapy.Request(url=url,callback=self.parse)    #发送的是get请求,多页⾯解析过程⼀样,所以回调函数是parse()
scrapy.Request()  发送的是get请求
scrapy.FormRequest()  发送的是post请求
⽰例1:爬取某电影⽹站中电影名称和电影详情页中的导演信息(发送get请求,传item参数,封装到item
对象中)
- move.py
# -*- coding: utf-8 -*-
import scrapy
from moviePro.items import MovieproItem
class MovieSpider(scrapy.Spider):
name = 'movie'
# allowed_domains = ['']
start_urls = ['www.4567tv.tv/frim/index1.html']
#解析详情页中的数据
def parse_detail(self,response):
#a返回接收到的meta字典
item = a['item']
actor = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[3]/a/text()').extract_first()
item['actor'] = actor
yield item
def parse(self, response):
li_list = response.xpath('//li[@class="col-md-6 col-sm-4 col-xs-3"]')
for li in li_list:
item = MovieproItem()
name = li.xpath('./div/a/@title').extract_first()
detail_url = 'www.4567tv.tv'+li.xpath('./div/a/@href').extract_first()
item['name'] = name
#meta参数:请求传参.meta字典就会传递给回调函数的response参数
yield scrapy.Request(url=detail_url,callback=self.parse_detail,meta={'item':item})
- items.py
import scrapy
class MoveproItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
actor = scrapy.Field()
- settings.py
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36' # rules
ROBOTSTXT_OBEY = False
⽰例2:百度翻译中翻译“dog”,发送的是post请求(重写 start_requests() ⽅法)
# -*- coding: utf-8 -*-
import scrapy
class PostSpider(scrapy.Spider):
name = 'post'
# allowed_domains = ['']
start_urls = ['fanyi.baidu/sug']
def start_requests(self):  # 重写该⽅法,发送的是post请求,scrapy.FormRequest()
data = {
'kw':'dog'
}
for url in self.start_urls:
# yield scrapy.Request(url=url,callback=self.parse)  #本来该函数封装的是对url的get请求,scrapy.Request()
yield scrapy.FormRequest(url=url,callback=self.parse,formdata=data)    #这⾥重写,
def parse(self, response):
)
备注:
  1、parse(self,response) 中的response,默认是start_urls中 get 请求后,返回的对象
  2、要发送post请求,需要重写start_requests(self)⽅法,使⽤ scrapy.FormRequest()
  3、get请求,scrapy.Request()
  - 在使⽤scrapy crawl spiderFileName运⾏程序时,在终端⾥打印输出的就是scrapy的⽇志信息。
  - ⽇志信息的种类:
        ERROR :⼀般错误
        WARNING : 警告
        INFO : ⼀般的信息
        DEBUG :调试信息
  - 设置⽇志信息指定输出:
    在settings.py配置⽂件中,加⼊
LOG_LEVEL = ‘指定⽇志信息种类’即可。
LOG_FILE = ''则表⽰将⽇志信息写⼊到指定⽂件中进⾏存储
- settings.py
LOG_LEVEL = "ERROR"      #添加之后,只有出错的时候才会打印错误信息
中间件的使⽤⼀定要在settings.py中添加类,不然⽆法执⾏。
⼀.下载中间件
先祭出框架图:
解释如下:
  - 引擎(Scrapy)
    ⽤来处理整个系统的数据流处理,触发事务(框架核⼼)
  - 调度器(Scheduler)
    ⽤来接收引擎发过来的请求,压⼊队列中,并在引擎再次请求的时候返回,可以想象成⼀个URL(抓取⽹页的⽹址或者说是链接)的优先队列,由它来决定下⼀个要抓取的⽹址是什么,同时去除重复的⽹址
  - 下载器(Downloader)
    ⽤于下载⽹页内容,并将⽹页内容返回给蜘蛛(Scrapy下载器是建⽴在twisted这个⾼效的异步模型上的)
  - 爬⾍(Spiders)
    爬⾍是主要⼲活的,⽤于从特定的⽹页中提取⾃⼰需要的信息,即所谓的实体(Item)。⽤户也可以从中提取出链接,让scrapy继续抓取下⼀个页⾯
  - 项⽬管道(Pipeline)
    负责处理爬⾍从⽹页中抽取的实体,主要的功能是持久化实体,验证实体的有效性,清除不需要的信息。当页⾯被爬⾍解析后,将被发送到项⽬管道,并经过⼏个特定的次序处理数据
下载中间件(Downloader Middlewares)位于scrapy引擎和下载器之间的⼀层组件。
- 作⽤:
(1)引擎将请求传递给下载器过程中,下载中间件可以对请求进⾏⼀系列处理。⽐如设置请求的 User-Agent,设置代理等
(2)在下载器完成将Response传递给引擎中,下载中间件可以对响应进⾏⼀系列处理。⽐如进⾏gzip解压等。
我们主要使⽤下载中间件处理请求,⼀般会对请求设置随机的User-Agent ,设置随机的代理。⽬的在于防⽌爬取⽹站的反爬⾍策略。
⼆、UA池(User-Agent)和代理池(使⽤中间件实现)
1、UA池:User-Agent池
- 作⽤:尽可能多的将scrapy⼯程中的请求伪装成不同类型的浏览器⾝份。
- 操作流程:
1.在下载中间件中拦截请求
2.将拦截到的请求的请求头信息中的UA进⾏篡改伪装
3.在配置⽂件中开启下载中间件
2、代理池
- 作⽤:尽可能多的将scrapy⼯程中的请求的IP设置成不同的。
- 操作流程:
1.在下载中间件中拦截请求
2.将拦截到的请求的IP修改成某⼀代理IP
3.在配置⽂件中开启下载中间件
# middles.py
import random
# 中间件要写在下载中间件中
class MiddleproDownloaderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
t(s.spider_opened, signal=signals.spider_opened)
return s
user_agent_list = [
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 "
"(KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
"Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 "
"(KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 "
"(KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 "
"(KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 "
"(KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 "
"(KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 "
"(KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
连接apple id服务器时出错"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 "
"(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 "
"(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]
# 可被选⽤的代理IP
PROXY_http = [
'153.180.102.104:80',
'195.208.131.189:56055',
]
PROXY_https = [
'120.83.49.90:9000',
'95.189.112.214:35508',
]
# 拦截所有未发⽣异常的请求
def process_request(self, request, spider):
print(111)
# 使⽤UA池进⾏请求的UA伪装  # 为所有的请求添加 User-Agent
request.headers["User-Agent"] = random.choice(self.user_agent_list)  #随机选择user-agent,便于伪装⾝份return None  # 如果这⾥返回的是response,那么就不再执⾏下⾯的⽅法了
# 拦截所有的响应
def process_response(self, request, response, spider):
return response
# 拦截产⽣异常的请求
def process_exception(self, request, exception, spider):
print(222)
# 使⽤代理池进⾏请求代理ip的设置,
if request.url.split(":")[0] == "http":
else:
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# settings.py
  ⼀定要选择download_middlewares,  不能是spider_middlers
# Enable or disable spider middlewares
# See /en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
#    'middlePro.middlewares.MiddleproSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See /en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
'middlePro.middlewares.MiddleproDownloaderMiddleware': 543,      #添加该类
}
'''
在scrapy中使⽤selenium的编码流程:
1.在spider的构造⽅法中创建⼀个浏览器对象(作为当前spider的⼀个属性)
2.重写spider的⼀个⽅法closed(self,spider),在该⽅法中执⾏浏览器关闭的操作
3.在下载中间件的process_response⽅法中,通过spider参数获取浏览器对象

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。