Scrapy框架 学习笔记2

在这里记录一下学习过程中遇到的问题:

1.我们自定义的爬虫是处理的从返回的response中提取item的过程,那么,在发送请求到接受响应之间,如果存在一些异常,我们需要记录下来:

首先要知道,在srapy遇到异常之后,会在你允许的情况下重试这个网页,那么我们可以自定义一个RetryMiddleware:

#自定义的下载中间件,用于记录下没有返回响应的异常网页
from scrapy.downloadermiddlewares.retry import RetryMiddleware
from scrapy.exceptions import NotConfigured
class myre(RetryMiddleware):
    def __init__(self, settings):
        if not settings.getbool('RETRY_ENABLED'):
            raise NotConfigured
        self.max_retry_times = settings.getint('RETRY_TIMES')
        self.retry_http_codes = set(int(x) for x in settings.getlist('RETRY_HTTP_CODES'))
        self.priority_adjust = settings.getint('RETRY_PRIORITY_ADJUST')
        self.errfile = open('C:/python/errurl.txt','wb')
        
    def process_exception(self, request, exception, spider):
        self.errfile.write((request.url+'\t'+exception.__str__()+'\r\n').encode('utf-8'))
        return None

在这里,我们修改了process_exception()方法:不进行重试而是记录下出错的网址和异常内容。

同时需要在setting文件中导入自定义的中间件

RETRY_ENABLED = True#可重试以及重试次数
RETRY_TIMES = 1
DOWNLOADER_MIDDLEWARES = {
    'week1.spiders.myter.mymw':345#自定义的下载中间件
}

2.读取特别大的文件的时候应该行读:
f3 = open('C:/python/dojieba.txt','w')
for line in done:

或者
for i in range(5000):#试处理5000个网页
    url = f.readline().split('\t')[0].strip()

3.scrapy会过滤掉一些常见的网络错误,想要获得他们:

class Spider1(Spider):
	handle_httpstatus_list = [301,302,307,404,502,504]#能够处理网页的常见的错误
        othercodes...
def parse(self , response):<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">	item = Week1Item()#完善item</p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">	url = response.request.url</p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">	if 'redirect_urls' in response.meta:#如果网页重定向,获得一开始的网址。 request.meta 会复制给response.meta</p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">   		url = response.request.meta['redirect_urls'][0]</p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">	item['url_status'] =url+'\t'+str(response.status)+'\r\n'</p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">	if response.status != 200:#不对出错的网页进一步处理</p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">		return item</p>
在我们自定义的spider中处理这些错误,常见的404,502等等我们在文件中输出他们,
class Week1Pipeline(object):
    def __init__(self):
        self.file = open('C:/python/results.txt','wb')#记录结果
        self.errfile = open('C:/python/notfound_url.txt','wb')#记录出错的网页
        
    def process_item(self, item, spider):
            if int(item['url_status'].split('\t')[1]) != 200:
                self.errfile.write(item['url_status'].encode('utf-8'))
                return item
            line = item['url']+'\t'+item['content']+'\r\n'
            self.file.write(line.encode('utf-8'))
            return item
而对于重定向的一些网站,他的原网址会存在request.meta中,scrapy会将meta复制给response,所以我们可以通过response.meta来获得他们的原来的url(meta['redirect_urls']是一个列表,每次转向都会存放下转向前的网址)

4.对于想获取的页面为空的情况,我们也要完善item:

if head!=[]:#空<head>的情况
	headtext = head[0].extract()
else:
	item['url'] = url
	item['content'] = 'EmptyHead'
	return item

5.某些网站中编码特殊,要区别对待,这里举一例错误的编码 gbk2312 他会使得网页的文字一场显示为 u'GBK编码',这种情况下既不能编码为GBK,也不能解码为unicode,可以通过这一步操作取消他的unicode识别:

p_bm = re.compile('charset=.*?gbk2312')#处理特殊的网页中文编码问题
	bm = re.findall(p_bm,headtext)
	if bm != []:
		headtext = headtext.encode('unicode-escape').decode('string_escape').decode('gbk')



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值