简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息

时间:2023-03-08 23:06:16
简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息

简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息

简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息


系统环境:Fedora22(昨天已安装scrapy环境)

爬取的开始URL:http://hr.tencent.com/position.php?lid=2156

target:爬取职位名称、职位类别、人数、地点、发布时间

如下

简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息


①创建项目

scrapy startproject hrtencent

然后cd hrtencent

②修改items.py

# -*- coding: utf-8 -*-
import scrapy

class HrtencentItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
name=scrapy.Field()
classification=scrapy.Field()
number=scrapy.Field()
location=scrapy.Field()
time=scrapy.Field()

name将用来装职位名称,classification将用来装职位类别,number将用来装人数,location将用来装地点,time将用来装发布时间。用于对应之后创建的spider.py文件中的item['name']=table.xpath('td/a[@target="_blank"]/text()').extract()

③在/hrtencent/spiders/文件夹下创建hrtencent_spider.py文件

# -*- coding: utf-8 -*-
import scrapy
from hrtencent.items import HrtencentItem

class HrtencentSpider(scrapy.Spider):
name='hrtencent'
allowed_domains=['hr.tencent.com']
start_urls=[
"http://hr.tencent.com/position.php?lid=2156"
]

def parse(self,response):
for table in response.xpath('//tr[@class="even" or @class="odd"]'):
item=HrtencentItem()
item['name']=table.xpath('td/a[@target="_blank"]/text()').extract()
item['classification']=table.xpath('td[2]/text()').extract()
item['number']=table.xpath('td[3]/text()').extract()
item['location']=table.xpath('td[4]/text()').extract()
item['time']=table.xpath('td[5]/text()').extract()
yield item

# 翻页
next_page=response.xpath('//a[@id="next"]/@href')
if next_page:
url=response.urljoin(next_page[0].extract())
yield scrapy.Request(url,self.parse)

相关代码说明:

i.编码声明,模块文件scrapy导入

# -*- coding: utf-8 -*-
import scrapy
from hrtencent.items import HrtencentItem #从hrtencent/items.py文件引入模块HrtencentItem

ii.创建类HrtencentSpider

class HrtencentSpider(scrapy.Spider):
name='hrtencent' #独一无二的名称,用于之后scrapy crawl (name)运行
allowed_domains=['hr.tencent.com'] #爬取的范围
start_urls=[
"http://hr.tencent.com/position.php?lid=2156"
] #start_urls是spider抓取网页的起始点,可以包括多个url

iii.parse方法是spider抓到一个网页以后默认调用的callback,避免使用这个名字来定义自己的方法。

当spider拿到url的内容以后,会调用parse方法,并且传递一个response参数给它,response包含了抓到的网页的内容,在parse方法里,你可以从抓到的网页里面解析数据。

def parse(self,response):
for table in response.xpath('//tr[@class="even" or @class="odd"]'):
item=HrtencentItem()
item['name']=table.xpath('td/a[@target="_blank"]/text()').extract()
item['classification']=table.xpath('td[2]/text()').extract()
item['number']=table.xpath('td[3]/text()').extract()
item['location']=table.xpath('td[4]/text()').extract()
item['time']=table.xpath('td[5]/text()').extract()
yield item

# 翻页
next_page=response.xpath('//a[@id="next"]/@href')
if next_page:
url=response.urljoin(next_page[0].extract())
yield scrapy.Request(url,self.parse)


△.当需要单纯的把网页内容保存到文件里,可以这么写:

def parse(self, response):
filename = response.url.split("/")[-2]
open(filename, 'wb').write(response.body)

△.关于上面的xpath的编写有两点要谈:

  • 关于Bash shell的scrapy shell (url)命令的使用
  • 关于网页元素审查的问题

这两点就放在一起讲吧。

例如,我要提取SNG12-腾讯云产品策划经理(北京)这条信息,右键超链接审查元素发现

简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息

图上发现,该条信息处于<tr class="even"><td><a target="_blank"></a></td></tr>的包围中,接着还可以知道别的要提取的信息,例如地点:北京啊、招聘人数:1啊什么的都在<tr class="even"></tr>的包围中,甚至下一条信息18428-手Q支付Android开发工程师(北京)

简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息

也只是把"even"变成了"odd"

于是,总体的xpath可以这么写

for table in response.xpath('//tr[@class="even" or @class="odd"]'):

而下面的各项,如:

item['name']=table.xpath('td/a[@target="_blank"]/text()').extract()

则是按照table所识别标签往下递推,所以总体路径应该为tr[@class="even" or @class="odd"/td/a[@target="_blank"]/text(),其中text()是指提取标签之间的文字,extract()则是将其输出为字符串,这么说,next_page=response.xpath('//a[@id="next"]/@href')@href就是提取标签中的url

提取到想要的字符串以后,不知道是否正确,可以使用scrapy shell (url),如下在bash shell中演示

[KANO@kelvin hrtencent]$ scrapy shell "http://hr.tencent.com/position.php?lid=2156"
2015-11-29 14:45:19 [scrapy] INFO: Scrapy 1.0.3 started (bot: hrtencent)
2015-11-29 14:45:19 [scrapy] INFO: Optional features available: ssl, http11
2015-11-29 14:45:19 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'hrtencent.spiders', 'SPIDER_MODULES': ['hrtencent.spiders'], 'LOGSTATS_INTERVAL': 0, 'USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.54 Safari/536.5', 'BOT_NAME': 'hrtencent'}
2015-11-29 14:45:19 [scrapy] INFO: Enabled extensions: CloseSpider, TelnetConsole, CoreStats, SpiderState
2015-11-29 14:45:19 [scrapy] INFO: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, MetaRefreshMiddleware, HttpCompressionMiddleware, RedirectMiddleware, CookiesMiddleware, ChunkedTransferMiddleware, DownloaderStats
2015-11-29 14:45:19 [scrapy] INFO: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware
2015-11-29 14:45:19 [scrapy] INFO: Enabled item pipelines:
2015-11-29 14:45:19 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023
2015-11-29 14:45:19 [scrapy] INFO: Spider opened
2015-11-29 14:45:19 [scrapy] DEBUG: Crawled (200) <GET http://hr.tencent.com/position.php?lid=2156> (referer: None)
[s] Available Scrapy objects:
[s] crawler <scrapy.crawler.Crawler object at 0x7f5cc1878050>
[s] item {}
[s] request <GET http://hr.tencent.com/position.php?lid=2156>
[s] response <200 http://hr.tencent.com/position.php?lid=2156>
[s] settings <scrapy.settings.Settings object at 0x7f5cb1009d50>
[s] spider <HrtencentSpider 'hrtencent' at 0x7f5cade4a650>
[s] Useful shortcuts:
[s] shelp() Shell help (print this help)
[s] fetch(req_or_url) Fetch request (or URL) and update local objects
[s] view(response) View response in a browser

>>> response.xpath('//tr[@class="even" or @class="odd"]/td/a[@target="_blank"]/text()').extract()
[u'SNG12-\u817e\u8baf\u4e91\u4ea7\u54c1\u7b56\u5212\u7ecf\u7406\uff08\u5317\u4eac\uff09', u'18428-\u624bQ\u652f\u4ed8Android\u5f00\u53d1\u5de5\u7a0b\u5e08\uff08\u5317\u4eac\uff09', u'17605-\u6218\u7565\u5408\u4f5c\u7ecf\u7406\uff08\u5317\u4eac\uff09', u'SA-\u5e7f\u70b9\u901a\u5e7f\u544a\u8d28\u91cf\u4f18\u5316\u5de5\u7a0b\u5e08(\u5317\u4eac)', u'OMG231-\u817e\u8baf\u7f51\u65b0\u95fb\u540e\u53f0\u5f00\u53d1\u9ad8\u7ea7\u5de5\u7a0b\u5e08\uff08\u5317\u4eac\uff09', u'WXG06-\u5fae\u4fe1\u652f\u4ed8\u6280\u672f\u652f\u6301\u5de5\u7a0b\u5e08\uff08\u5317\u4eac\uff09', u'OMG192-OMG192-\u817e\u8baf\u7f51\u534e\u5317\u6e20\u9053\u8425\u6536\u7ba1\u7406\uff08\u5317\u4eac\uff09', u'MIG08-\u9ad8\u7ea7\u4ea4\u4e92\u8bbe\u8ba1\u5e08\uff08\u5317\u4eac\uff09', u'SA-\u4e2d\u957f\u5c3e\u5e7f\u544a\u6570\u636e\u5206\u6790\u7ecf\u7406(\u5317\u4eac)', u'OMG232-\u817e\u8baf\u7f51\u5a31\u4e50\u89c6\u9891\u8282\u76ee\u7f16\u5bfc\uff08\u5317\u4eac\uff09']
>>> exit()

好奇为何是一堆\u吧,其实这是unicode,需要utf-8编码转换。

随便选一个u'SNG12-\u817e\u8baf\u4e91\u4ea7\u54c1\u7b56\u5212\u7ecf\u7406\uff08\u5317\u4eac\uff09',用unicode编码转换器试试看,

简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息

是我们所需要的内容,没错了吧~那就可以往代码上写了

注:输出来的从csv也有可能出现乱码现象,只要把编码改改就能看了~


*有关XPath的详细使用编写,还是另开一个文章吧。以上是简单介绍。

④运行写入csv

scrapy crawl hrtencent -o test.csv

简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息

一共爬取了261条信息,后续还可以直接使用excel来进行汇总,分析。

甚至可以把爬取范围扩大到全国,然后把数据导入R进行更加专业的分析。相关问题可以看我之前的笔记~