『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) + ',\n'
        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"},

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

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

posted @ 2017-08-27 10:51  叠加态的猫  阅读(1480)  评论(0编辑  收藏  举报