简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息
简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息
系统环境:Fedora22(昨天已安装scrapy环境)
爬取的开始URL:http://hr.tencent.com/position.php?lid=2156
target:爬取职位名称、职位类别、人数、地点、发布时间
如下
①创建项目
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-腾讯云产品策划经理(北京)
这条信息,右键超链接审查元素发现
图上发现,该条信息处于<tr class="even"><td><a target="_blank"></a></td></tr>
的包围中,接着还可以知道别的要提取的信息,例如地点:北京
啊、招聘人数:1
啊什么的都在<tr class="even"></tr>
的包围中,甚至下一条信息18428-手Q支付Android开发工程师(北京)
也只是把"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编码转换器试试看,
是我们所需要的内容,没错了吧~那就可以往代码上写了
注:输出来的从csv也有可能出现乱码现象,只要把编码改改就能看了~
*有关XPath的详细使用编写,还是另开一个文章吧。以上是简单介绍。
④运行写入csv
scrapy crawl hrtencent -o test.csv
一共爬取了261条信息,后续还可以直接使用excel来进行汇总,分析。
甚至可以把爬取范围扩大到全国,然后把数据导入R进行更加专业的分析。相关问题可以看我之前的笔记~