前言
上一关,我们学习了Scrapy框架 ,知道了Scrapy爬虫公司的结构和工作原理。 在Scrapy 爬虫公司里,引擎是最大的boss,统领着调度器、下载器、爬虫和数据管道四大部门。
这四大部门都听命于引擎,视引擎的需求为最高需求。
我们还通过实操爬取豆瓣Top250图书的项目,熟悉了Scrapy的用法。 这一关,我会带你实操一个更大的项目——用Scrapy爬取招聘网站的招聘信息。
你可以借此体验一把当Scrapy爬虫公司CEO的感觉,用代码控制并操作整个Scrapy的运行。
那我们爬取什么招聘网站呢?在众多招聘网站中,我挑选了职友集。这个网站可以通过索引的方式,搜索到全国上百家招聘网站的最新职位。
现在,请你用浏览器打开职友集的网址链接(一定要打开哦):
https://www.jobui.com/rank/company/view/beijing/
我用的是北京的页面,大家可以根据自己的需要来进行更换地区。
我们先对这个网站做初步的观察,这样我们才能明确项目的爬取目标。
明确目标
打开网址后,你会发现:这是职友集网站的地区企业排行榜,里面含有本月人气企业榜。
点击【北京痘印信息服务有限公司】,会跳转到这家公司的详情页面,再点击【招聘】,就能看到这家公司正在招聘的所有岗位信息。
初步观察后,我们可以把爬取目标定为:先爬取企业排行榜四个榜单里的公司,再接着爬取这些公司的招聘信息。
每个榜单有10家公司,四个榜单一共就是40家公司。也就是说,我们要先从企业排行榜爬取到这40家公司,再跳转到这40家公司的招聘信息页面,爬取到公司名称、职位、工作地点和招聘要求。
分析过程
明确完目标,我们开始分析过程。首先,要看企业排行榜里的公司信息藏在了哪里。
企业排行榜的公司信息
请你右击打开“检查”工具,点击Network,刷新页面。点开第0个请求beijing/,看Response,找一下有没有榜单的公司信息在里面。
一找,发现四个榜单的所有公司信息都在里面。说明企业排行榜的公司信息就藏在html里。
现在请你点击Elements,点亮光标,再把鼠标移到【北京抖音信息服务有限公司】,这时就会定位到含有这家公司信息的元素上。
点击href=“/company/10375749/”,会跳转到字节跳动这家公司的详情页面。详情页面的网址是:
https://www.jobui.com/company/17376344/
我们可以猜到:/company/+数字/应该是公司id的标识。这么一观察,榜单上的公司详情页面的网址规律我们就得出来了。
那么,我们只要把元素的href属性的值提取出来,就能构造出每家公司详情页面的网址。
构造公司详情页面的网址是为了后面能获得详情页面里的招聘信息。
现在,我们来分析html的结构,看看怎样才能把元素href属性的值提取出来。
仔细观察html的结构,你会发现,每个公司信息都藏在一个元素里,这个div标签中包
和
两个div。
我们想要的标签,就在里面。
我们想拿到所有元素href属性的值。我们当然不能直接用find_all()抓取标签,原因也很简单:这个页面有太多的标签,会抓出来很多我们不想要的信息。
一个稳妥的方案是:先抓取最外层的标签,再抓取
标签里的
元素,最后提取到
元素href属性的值。就像剥洋葱,要从最外面的一层开始剥一样。
分析到这里,我们已经知道公司详情页面的网址规律,和如何提取元素href属性的值。
接下来,我们需要分析的就是,每家公司的详情页面。
公司详情页面的招聘信息
我们打开【北京字节跳动科技有限公司】的详情页面,点击【招聘】。这时,网址会发生变化,多了jobs的参数。
如果你多点击几家公司的详情页面,查看招聘信息,就会知道:公司招聘信息的网址规律也是有规律的。
接着,我们需要找找看公司的招聘信息都存在了哪里。
还是在字节跳动公司的招聘信息页面,右击打开“检查”工具,点击Network,刷新页面。我们点击第0个请求jobs/,查看Response,翻找看看里面有没有这家公司的招聘信息。
在Response里我们找到了想要的招聘信息。这说明公司的招聘信息依旧是藏在了html里。
接下来,你应该知道要分析什么了吧。
分析的套路都是相同的,知道数据藏在html后,接着是分析html的结构,想办法提取出我们想要的数据。
那就按照惯例点击Elements,然后点亮光标,把鼠标移到公司名称吧。
公司名称藏在标签下的
元素的文本中。按道理来说,我们可以通过class属性,定位到
的这个标签,取出
标签的文本,就能拿到公司名称。
不过经过我几次的操作试验,发现职友集这个网站间隔一段时间就会更换这个标签的名字(可能你此时看到的标签名不一定是
)。
为了保证一定能取到公司名称,我们改成用id属性(id=“companyH1”)来定位这个标签。这样,不管这个标签名字如何更换,我们依旧能抓到它。
下面,再把鼠标移到岗位名称,看看招聘的岗位信息可以怎么提取。
你会发现:每个岗位的信息都藏在一个标签下,职位名称在
元素的文本中,工作地点和职位要求在
元素中,工作地点在第 1 个
标签里,职位要求在第 2 个
标签里。
这样分析下来,我们想要的招聘信息,包括公司名称、职位名称、工作地点和职位要求,都定位清楚了。
至此,我们分析完了整个爬取过程,接下来就是代码实现啦。
代码实现
我们按照Scrapy正常的用法一步步来。首先,我们必须创建一个Scrapy项目。
创建项目
还记得怎么创建吗?打开本地电脑的终端(windows:Win+R,输入cmd;mac:command+空格,搜索“终端”),跳转到你想要保存项目的目录下,输入创建Scrapy项目的命令:scrapy startproject jobui(jobui是职友集网站的英文名,在这里我们把它作为Scrapy项目的名字)。
创建好项目后,你在本地电脑的编译器打开这个Scrapy项目,会看到如下的结构:
定义item
我们刚刚分析的时候,已经确定要爬取的数据是公司名称、职位名称、工作地点和招聘要求。
那么,现在请你写出定义item的代码。
下面,是我写的定义item的代码。
import scrapy
class JobuiItem ( scrapy. Item) :
company = scrapy. Field( )
position = scrapy. Field( )
address = scrapy. Field( )
detail = scrapy. Field( )
创建和编写爬虫文件
定义好item,我们接着要做的是在spiders里创建爬虫文件,命名为jobui_ jobs。
现在,我们可以开始在这个爬虫文件里编写代码。
先导入所需的模块:
import scrapy
import bs4
from . . items import JobuiItem
接下来,是编写爬虫的核心代码。我会先带着你理清代码的逻辑,这样等下你才能比较顺利地理解和写出代码。
在前面分析过程的步骤里,我们知道要先抓取企业排行榜40家公司的id标识,比如字节跳动公司的id标识是/company/17376344/。
再利用抓取到的公司id标识构造出每家公司招聘信息的网址。比如,字节跳动公司的招聘信息网址就是https://www.jobui.com/company/17376344/jobs/
我们需要再把每家公司招聘信息的网址封装成requests对象。这里你可能有点不理解为什么要封装成requests对象,我解释一下。
如果我们不是使用Scrapy,而是使用requests库的话,一般我们得到一个网址,需要用requests.get(),传入网址这个参数,才能获取到网页的源代码。
而在Scrapy里,获取网页源代码这件事儿,会由引擎交分配给下载器去做,不需要我们自己处理。我们之所以要构造新的requests对象,是为了告诉引擎,我们新的请求需要传入什么参数。
这样才能让引擎拿到的是正确requests对象,交给下载器处理。
既然构造了新的requests对象,我们就得定义与之匹配的用来处理response的新方法。这样才能提取出我们想要的招聘信息的数据。
好啦,核心代码的逻辑我们理清楚了。
我们接着往下写核心代码。
import scrapy
import bs4
from . . items import JobuiItem
class JobuiSpider ( scrapy. Spider) :
name = 'jobui'
allowed_domains = [ 'www.jobui.com' ]
start_urls = [ 'https://www.jobui.com/rank/company/view/beijing/' ]
def parse ( self, response) :
bs = bs4. BeautifulSoup( response. text, 'html.parser' )
company_list = bs. find( 'div' , id = "companyList" ) . find_all( 'div' , class_= 'c-company-list' )