python爬虫url去重_python学习:python爬虫之Scrapy框架(2):请求队列,页面持久化,url去重,Cookie...

本文深入探讨Scrapy框架的使用,包括如何使用Request将请求加入队列,利用Pipline和Item进行页面信息持久化,详细解析Scrapy的URL去重机制,并介绍了如何在爬虫中管理和使用Cookie。同时,文章提供了自定义去重类的示例以及设置登录Cookies的方法。
摘要由CSDN通过智能技术生成

Scrapy框架

scrapy框架学习进阶:

这里接scrapy框架(1)的内容,

1、使用Request将新的请求加入请求队列;

2、使用pipline和item对返回页面信息持久化;

3、Scrapy的url去重源码;

4、cookie的使用;

4Request递归访问

使用Request,进行递归遍历:

from scrapy.http importRequest

#将新的url加入调度器,然后递归遍历解析

yield Request(url=new_url,callback=self.parse)

在setting.py文件中可以设置递归查找层数:

DEPTH_LIMIT = 1

5Pipline和item持久化

使用pipline将title和url持久化

在items.py增加对应持久化对象

示例:

#保存抽屉网新闻title和href

classChoutiItem(scrapy.Item):

title =scrapy.Field()

href =scrapy.Field()

在chouti.py导入对应Item

from ..items importChoutiItem

#创建item

choutiItem = ChoutiItem(title = a_detail,href =a_href)

#返回item

yield choutiItem

在pipelines.py加入查看item,这里也可以将item写入文件,

open_spider方法,spider打开时调用;

close_spider方法,spider关闭时调用;

from_crawler方法新建类对象,获取settings的配置内容,可以用来获取数据库信息,然后在__init__方法中初始化连接。

classProScrapyPipeline(object):

#初始化方法

def __init__(self):

pass

#返回类对象

@classmethod

deffrom_crawler(cls,crawler):

#将settings.py文件封装到settings参数

val = crawler.settings.get("DUPEFILTER_CLASS")

print(val)

returncls()

#爬虫打开时调用

defopen_spider(self,spider):

self.f = open("news.txt", 'a', encoding='utf-8')

print("pipline open")

#爬虫关闭时调用

defclose_spider(self,spider):

self.f.close()

print("pipline close")

defprocess_item(self, item, spider):

#查看spider,item

file = item["title"] + '\n' + item['href'] + '\n'

print(file)

#将信息写入文件

self.f.write(file)

#其他pipline继续处理item

return item

修改settings.py,让pipeline生效,取消注释:

可以加入多个Pipline做不同处理,300表示优先级,越小优先级越高。

ITEM_PIPELINES ={

'Pro_scrapy.pipelines.ProScrapyPipeline': 300,

}

如果process_item方法return item,那么所有Pipline根据优先级依次处理该item,不想该item处理需要raise dropitem。

from scrapy.exceptions importDropItem

#如果不想其他pipline处理这个item

raise DropItem

6URL访问去重

使用set()集合去重,将url放入set集合。

使用md5加密url,以固定长度存入数据库,使用set()可以将重复url去重。

示例:

#保存url,使用set,去重

urls_set =set()

#md5加密url

md5_url =self.md5(a_href)

if md5_url not inself.urls_set:

self.urls_set.add(md5_url)

print(a_detail,a_href)

defmd5(self,url):

importhashlib

obj =hashlib.md5;

obj.update(bytes(url,encoding='utf-8'))

return obj.hexdigest()

Scrapy自带有url去重功能,使用类RFPDupeFilter实现去重。

示例:

#获取返回网页所有a标签,标签列表

a_list = Selector(response=response).xpath('//a/@href')

for url ina_list:

#递归遍历所有url,dont_filter调用scrapy提供的url去重

yield Request(url=url,callback=self.parse,dont_filter=True)

scrapy的去重源码:

from scrapy.dupefilters importRFPDupeFilter

classRFPDupeFilter(BaseDupeFilter):

"""Request Fingerprint duplicates filter"""

def __init__(self, path=None, debug=False):

self.file =None

self.fingerprints =set()

self.logdupes =True

self.debug =debug

self.logger = logging.getLogger(__name__)

ifpath:

self.file = open(os.path.join(path, 'requests.seen'), 'a+')

self.file.seek(0)

self.fingerprints.update(x.rstrip() for x inself.file)

@classmethod

deffrom_settings(cls, settings):

debug = settings.getbool('DUPEFILTER_DEBUG')

returncls(job_dir(settings), debug)

defrequest_seen(self, request):

fp =self.request_fingerprint(request)

if fp inself.fingerprints:

returnTrue

self.fingerprints.add(fp)

ifself.file:

self.file.write(fp +os.linesep)

defrequest_fingerprint(self, request):

returnrequest_fingerprint(request)

defclose(self, reason):

ifself.file:

self.file.close()

deflog(self, request, spider):

ifself.debug:

msg = "Filtered duplicate request: %(request)s (referer: %(referer)s)"args = {'request': request, 'referer': referer_str(request) }

self.logger.debug(msg, args, extra={'spider': spider})

elifself.logdupes:

msg = ("Filtered duplicate request: %(request)s"

"- no more duplicates will be shown"

"(see DUPEFILTER_DEBUG to show all duplicates)")

self.logger.debug(msg, {'request': request}, extra={'spider': spider})

self.logdupes =False

spider.crawler.stats.inc_value('dupefilter/filtered', spider=spider)

我们可以自定义去重类,类似于RFPDupeFilter

#自定义UR'L去重类

classDuplicationFilter(object):

def __init__(self):

#创建set集合

self.urlset =set()

@classmethod

deffrom_settings(cls, settings):

returncls()

defrequest_seen(self, request):

if request.url inself.urlset:

returnTrue

#将url加入set

self.urlset.add(request.url)

print(self.urlset)

returnFalse

def open(self): #can return deferred

print("open")

defclose(self, reason):

print("close")

deflog(self, request, spider):

pass

在settings.py配置我们的自定义类

示例:

#配置url去重类

DUPEFILTER_CLASS = 'Pro_scrapy.duplicationfilter.DuplicationFilter'

7登陆cookies

使用cookies,需要导入相应包,创建对象保存cookie。

示例:

导入相应包:

fromscrapy.http.cookies importCookieJar

修改chouti.py,def parse()方法中编写代码:

#创建cookiejar对象,保存cookie容器

cookie_obj =CookieJar()

#获取当前请求的cookie,保存到cookieJar对象

cookie_obj.extract_cookies(response,response.request)

#拿到cookie

print(cookie_obj._cookies)

#带上用户名密码登陆,发送请求

yieldRequest(

url="https://dig.chouti.com/login",

method="POST",

body="phone=+861832573226&password=11223&loginType=2",

headers="{'Content-Type':' application/x-www-form-urlencoded; charset=UTF-8'}",

cookies=cookie_obj._cookies,

callback=self.loginSuc

)

defloginSuc(self,response):

print(response)

#登陆成功访问其他页面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值