51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 1389|回复: 1
打印 上一主题 下一主题

scrapy框架的使用心得

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-6-11 11:46:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
scrapy基础部分就不再做解析了,请移步:scrapy中文文档 https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/overview.html
此次对scrapy应用是基于二次开发的,利用scrapy的框架的爬取大致流程,自己独立写模块,可以使开发流程更为简洁明了,降低了程序内部耦合,在实际应用过程中有一定的通用性, 而又不拘泥于scrapy原生的语法。

接下来分析一下我的scrapy,spider部分的结构

class lagouSpider(scrapy.Spider):
    handle_httpstatus_list = [500,503, 504, 400, 403, 404, 408]
    name = "lagou"
    allowed_domains = ["lagou.com"]
    start_urls = [(url_prefix.format(i) , i, 'company') for i in range(1, 180000)]

    def make_requests_from_url(self,url):
        request = scrapy.Request(url[0], callback=self.handle_parse,errback = self.handle_error)
        request.meta['index'] = url[1]
        request.meta['type'] = url[2]
        return request

要点:
1.当make_requests_from_url函数存在时,自动执行,将start_urls的每一个元素传入该函数,该元素类型可以为多种,本例中格式为列表, 目的是方便传入url内容的类型(如:公司,职位), 将其保存为meta
2.我们利用meta来传递一些用于标识的数据, 例如在拉勾网中,我们要爬取的公司的id,职位的类型和页码

def handle_parse(self, response):
    baseinfo = {'index':response.meta['index']}        #这里baseinfo用来保存到本地文件中,后续我们将往里添加各种信息
     maininfo = parse_company(response)                #parse_company是独立写的解析模块中的函数,源代码见GitHub
     if 'err' in maininfo:                             #解析中遇到错误时会有err信息,没有的话说明解析正确,继续执行
         info = {}
         info['index'] = baseinfo['index']
         info['type'] = response.meta['type']
         info['err'] = maininfo['err']
         #baseinfo['type'] = "NotFound"
         if maininfo['err']=='404 NotFound':
             self.f_404.write(json.dumps(info))
             self.f_404.write('\n')
         else:
             self.f_retry.write(json.dumps(info))
             self.f_retry.write('\n')
     else:
         info={}
         info['index']= baseinfo['index']
         info['type']='company'
         info['data']=maininfo

         self.f_success.write(json.dumps(info))               #将收集到的公司的信息保存为json格式,该格式便于阅读和分析
         self.f_success.write('\n')
         self.f_success.flush()                               #将内存里的数据写入硬盘,可以在爬取的过程中读取

         postCount = maininfo['dataInfo']['positionCount']    #postCount是统计该公司的职位数量
         if postCount!=0:                                     #如果职位数量不为0,分类查找岗位
             for i in ['技术','产品','运营','市场与销售','职能','金融','设计']:
                 url_post_prefix = "https://www.lagou.com/gongsi/searchPosition.json?companyId={}&positionFirstType={}&pageNo={}&pageSize=10"
                 url = url_post_prefix.format(baseinfo['index'], i, 1)    #生成新的url及相关信息,这里的url包含了岗位类型,url,和页数
                 request = scrapy.Request(url,cookies=cookie, callback=self.handle_parse_post, errback = self.handle_error)    #这里要爬取的类型为职位,回调函数设置为handle_parse_post
                 request.meta['type'] = 'post'              
                 request.meta['index'] = baseinfo['index']
                 request.meta['postType'] = i
                 request.meta['pageNo'] = 1
                 yield request              #这里利用yield,将request传给回调函数的同时函数继续运行
                 print 'company:{}正在加载,岗位类型为{},当前岗位第{}页'.format(baseinfo['index'], i, 1)



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-4-27 12:46 , Processed in 0.065429 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表