zoukankan      html  css  js  c++  java
  • 『Scrapy』爬取腾讯招聘网站

    分析爬取对象

    初始网址,

    http://hr.tencent.com/position.php?@start=0&start=0#a

    (可选)由于含有多页数据,我们可以查看一下这些网址有什么相关

    page2:http://hr.tencent.com/position.php?@start=0&start=10#a

    page3:http://hr.tencent.com/position.php?@start=0&start=20#a

    也就是说末尾id每次递增10(#a无实际意义,输入start=0也能进入第一页)。

    确定想爬取的信息:

    我们爬取表格中的5类信息和每个招聘的具体网页地址,共6个条目,在查看源码的过程中我们可以使用F12开发者工具辅助定位,

    其中class=event的tr表示白色背景条目,class=odd表示灰色背景条目,点击开查看具体信息如下,

    爬虫编写

    使用框架初始化项目,

     scrapy startproject Tencent

     

    修改items.py,对应上面需要记录的六组数据,

    import scrapy
    
    
    class TencentItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        # 职位名
        positionName = scrapy.Field()
        # 职位详情链接
        positionLink = scrapy.Field()
        # 职位类别
        positionType = scrapy.Field()
        # 招聘人数
        peopleNumber = scrapy.Field()
        # 工作地点
        workLocation = scrapy.Field()
        # 发布时间
        publishtime = scrapy.Field()

    生成初始爬虫spider命名为tensent.py,

    scrapy genspider  tencent "tencent.com"

    修改tencent.py,注意函数需要返回item

    import scrapy
    from Tencent.items import TencentItem
    
    class TencentSpider(scrapy.Spider):
        name = "tencent"
        allowed_domains = ["tencent.com"]
    
        baseURL = "http://hr.tencent.com/position.php?@start="
        offset = 0
        start_urls = [baseURL + str(offset)]
    
        def parse(self, response):
            node_list = response.xpath("//tr[@class='even'] | //tr[@class='odd']")
    
            for node in node_list:
                item = TencentItem()
    
                # 职位名
                item['positionName'] = node.xpath("./td[1]/a/text()").extract()[0]
                print(node.xpath("./td[1]/a/text()").extract())
    
                # 职位详情链接
                item['positionLink'] = node.xpath("./td[1]/a/@href").extract()[0]
    
                # 职位类别
                if len(node.xpath("./td[2]/text()")):
                    item['positionType'] = node.xpath("./td[2]/text()").extract()[0]
                else:
                    item['positionType'] = ''
    
                # 招聘人数
                item['peopleNumber'] = node.xpath("./td[3]/text()").extract()[0]
    
                # 工作地点
                item['workLocation'] = node.xpath("./td[4]/text()").extract()[0]
    
                # 发布时间
                item['publishtime'] = node.xpath("./td[5]/text()").extract()[0]
    
                yield item
    
            # 换页方法一:直接构建url
            if self.offset <2190:
                self.offset += 10
                url = self.baseURL + str(self.offset)
                yield scrapy.Request(url, callback=self.parse)  # callback函数可以更换,即可以使用不同的处理方法处理不同的页面

    两个yield连用使得不同的调用次数函数输出不同的表达式,这是一个很好的技巧,不过第二个yield是可以替换为return的,毕竟提交一个新请求后引擎会自动调用parse去处理响应

    这里面使用提取下一页的方法是自己拼接之后的网址,这是一种相对而言笨拙一点的手法,一般会直接在网页中提取下一页的网址,但是这对于一些无法提取下一页网址的情况很实用。

    更新一下直接在网页提取下一页的方法,

            # 换页方法二:提取下页链接
            if not len(response.xpath("//a[@class='noactive' and @id='next']")):
                url = 'http://hr.tencent.com/' + response.xpath("//a[@id='next']/@href").extract()[0]
                yield scrapy.Request(url, callback=self.parse)

    对于静态页面这很容易,但是如果是动态页面就可能需要其他的辅助手段了。另外settings中有有关请求头文件的设置部分,有需求的话可以改写之。

    取消settings.py对于管线文件的注释,

    修改pipelines.py文件,

    import json
    
    class TencentPipeline(object):
        def __init__(self):
            self.f = open('tencent.json','w')
    
        def process_item(self, item, spider):
            content = json.dumps(dict(item),ensure_ascii=False) + ',
    '
            self.f.write(content)
            return item
    
        def close_spider(self,spider):
            self.f.close()

     这样一个初级的爬虫项目就完成了。

    测试并运行,

    scrapy check tencent

    scarpy srawl tencent

     打开保存的json文件,可以看到类似下面的输出,每一行为一条招聘信息,

    {"workLocation": "深圳", "positionType": "技术类", "positionName": "24111-安全架构师", "peopleNumber": "1", "publishtime": "2017-08-26", "positionLink": "position_detail.php?id=32378&keywords=&tid=0&lid=0"},

    完成后整个文件夹变化如下,

    实际爬取过程是要消耗一点时间的。

  • 相关阅读:
    ASP.NET WEB开发,实现上传图片
    使用Word API打开Word文档 ASP.NET编程中常用到的27个函数集
    工资单的编辑与保存
    生成工资表
    系统设置
    空间参考
    Envelope几何对象 Curve对象几何对象 Multipatch几何对象 Geometry集合接口 IGeometryCollection接口
    Polygone对象
    Segment,Path,Ring和Polyline对象
    [Android]使用ActivityGroup来切换Activity和Layout
  • 原文地址:https://www.cnblogs.com/hellcat/p/7435320.html
Copyright © 2011-2022 走看看