爬虫技术是一种一种使用代码抓取网页信息的技术,一般情况下使用Python语言来编写爬虫的脚本,其他的语言也部分的对爬虫技术有支持,但是应用不广泛。网络爬虫是一种能有条理并且系统化地浏览Web,以便收集网页数据的程序(通常也被称作“机器人”)。搜索引擎(例如谷歌,必应)利用爬虫来创建索引是网络爬虫最典型的使用案例。
下面是一个爬虫的简单例子,使用到了requets包和BeautifulSoup包。其中
- request包用于抓取网页信息
- BeautifulSoup包用于网页信息的提取
import requests
from bs4 import BeautifulSoup
# 搜索关键字为“数据挖掘”,工作地区为北京的url
# dps为工作地区的参数,010为猎聘网为北京地区指定的区域号
url="https://www.liepin.com/zhaopin/?key=数据挖掘&dqs=010"
# 发起访问GET请求
page = requests.get(url = url)
# 输出返回信息
print(page.url)
# 初始化 soup 对象,page.text为爬取到的带有html标签页面
soup = BeautifulSoup(page.text,"html.parser")
# 找到<h3>标签,实质是获取所有包含职位名称及链接的标签内容
soup = soup.find_all("h3")
#在每个<h3>中进行抽取链接信息
times =0
for i in soup:
#有些<h3>标签不包含求职信息,做简要判断
if i.has_attr("title"):
#抽取链接内容
href=i.find_all("a")[0]["href"]
print(href)
if times ==1 :
print("i = -----")
print(i)
times=times+1
# 输出为:
# https://www.liepin.com/job/1929399435.shtml
# https://www.liepin.com/job/1925362683.shtml
# https://www.liepin.com/job/1924144611.shtml
# https://www.liepin.com/job/1919418647.shtml
一般情况下也可以用正则表达式替代如果你对正则表达式感兴趣,可以去看我的另外一篇博客:Regular-Express01。
基础知识 #
需要学习爬虫,首先要了解计算机网络上的基础知识。
我们一般通过url,使用浏览器来访问互联网上的网页信息。
HTTP请求方法 #
HTTP 定义了一组请求方法, 以表明要对给定资源执行的操作。指示针对给定资源要执行的期望动作. 虽然他们也可以是名词, 但这些请求方法有时被称为HTTP动词. 每一个请求方法都实现了不同的语义。
- GET - GET方法请求一个指定资源的表示形式. 使用GET的请求应该只被用于获取数据。爬虫一般会使用GET请求获取信息。
- HEAD - HEAD方法请求一个与GET请求的响应相同的响应,但没有响应体。
URL结构 #
一个完整的启用了ssh加密的url结构如下(如过未启用ssh加密,则将https替换为http)
使用百度搜索spide的urlr: https://www.baidu.com/s?wd=spider&pn=90#button
我们来对上面的url进行拆解,可以得到以下的组成公式
[协议名] + [域名] + [路径] + [可选-参数] + [可选-浏览器锚点]
其中,必选参数:[协议名] + [域名] + [路径] 为https://www.baidu.com/s,一般情况下我们不需要特别的进行关心,我们需要关心的是[可选-参数],这里为wd=spyder和pn=90,[可选-参数]和前面的内容用?来进行分隔,[可选-参数]中的变量使用&来进行分隔。
这里wd=spyder就是我们传送给服务器的参数,百度的服务器通过这个来知道我们查询的内容是spyder,以此来返回我们需要的查询结果。
#button是浏览器锚点,一般用于同一个页面内的移动,我们可以不需要关心。
网页结构 #
一个简单的html结构如下,我们使用爬虫每次所获取的,就是一个类似下面结构的文本数据,一般情况下,我们所需要获取的内容就在body标签内,一般使用正则表达式或者XPATH等技术获取自己期望获得的信息。
<!-- 当前网页的标准规范声明 -->
<!DOCTYPE html>
<html>
<!-- 网页头信息 -->
<head>
<title>这里是网站的标题</title>
</head>
<!-- 网页css样式 -->
<style>
*{
text-align:center;
}
</style>
<!-- 网页内容信息 -->
<body>
<h1>这是一个标题</h1>
<div>这里是网页的一个块</div>
<a href='https://example.com'>这里是一个超链接</a>
</body>
<script>
console.log('hello world') // 网页的JavaScript脚本
</script>
</html>
反-反爬虫技术 #
Python爬虫要经历爬虫、爬虫被限制、爬虫反限制的过程。当然后续还要网页爬虫限制优化,爬虫再反限制的一系列道高一尺魔高一丈的过程。爬虫的初级阶段,添加headers和ip代理可以解决很多问题。
登陆状态模拟 - UA #
服务器通过用户请求中的User-Agent信息来识别用户的浏览器信息,所以我们可以通过自定义headers中的User-Agent的值来将我们的爬虫伪装成浏览器。不过此方法仅限于解决部分网站简单的反爬虫机制,一些网站需要使用代理IP解决。
IP代理 #
IP代理通过使用随机的IP来爬取目标网站,让服务器误以为是来自不同的电脑的正常访问,从而达到反-反爬虫的目的。具体细节可以参考 这篇博客。
模拟Cookies #
对于某些网站,内容会通过判断用户Cookies来进行动态加载,这时我们还需要在headers信息中添加自己浏览器的Cookies来进行内容的爬取,具体方式和UA模拟很像,不过也要注意防止同一Cookies访问次数过多而导致Cookies被封。
手把手教你爬取猎聘网 #
猎聘网是我们本次的目标爬取网站,计划爬取其中北京,上海,深圳,广州,武汉,杭州等地区的数据挖掘,图像算法工程师,java后端,互联网产品经理职位等信息。
首先我们对猎聘网的url进行分析:
下方是未选择城市时数据挖掘职位的url链接:
https://www.liepin.com/zhaopin/?key=数据挖掘
当对城市如北京,进行选择后,浏览器上面的url变成了
https://www.liepin.com/zhaopin/?dqs=010?key=数据挖掘
你实际上看到的url可能比我上面的url要复杂,原因是我将其中不重要的变量进行了删除,只保留了我们需要的变量,即城市和职位,一般情况下,手动删除url中的变量,尝试几次即可找到我们需要的变量。
通过上方的分析,我们可以知道猎聘网查询职位的url构成为
https://www.liepin.com/zhaopin/?key=[职位名]&[dqs=城市码]
这样我们可以使用Python根据上方的公式来构建url爬取不同地点的不同职位,这里我通过手动尝试的方式,找到了不同城市的dqs值并构建数组,代码如下:
# 猎聘网基础url
url = 'https://www.liepin.com/zhaopin/?'
# 待爬取的职位
jobs = ['数据挖掘', '图像算法工程师', 'java后端', '互联网产品经理']
# 待爬取的城市,和对应的dqs
citys = ['北京', '上海', '深圳', '广州', '武汉', '杭州']
cityIds = ['010', '020', '050090', '050020', '170020', '070020']
有了以上的信息,我们通过循环即可构造不同城市不同职位的url,如果想要实现翻页,原理也类似,这里不再进行叙述。
我们可以对代码进行一个简单的测试
import requests
# 这里填入上方的几个数组
# 构建url
target_url = url+'key='+jobs[0]+'&dqs='+cityIds[0]
# 用get方法爬取数据
getData = requests.get(url=target_url)
# 将获得的数据使用utf-8格式进行转码
finalHtmlData = getData.content.decode("utf-8")
# 预期的输出为爬取到的html内容
print(finalHtmlData)
上方就是一个最简单的爬取方式,你可以通过循环结构来构建不同职位的url来进行爬取,同时也可以通过正则或者其他包来对获取的finalHtmlData进行解析,获取我们需要的数据。
下面再来演示通过正则输出目标数据,假如我们想找到finalHtmlData中所有的职位url
regExpUrl = '<a[^>]*href=\"(https://www.liepin.com/job[^"]*)\"[^>]*'
import re
# 正则表达式匹配
finalAData = re.compile(regExpUrl).findall(finalHtmlData)
# 预期输出为一堆的url
for i in finalAData:
print(i)
正则表达式及其使用说明见我的另外一篇 博客
上方代码的完整整理如下:
import requests
# 这里填入上方的几个数组
# 猎聘网基础url
url = 'https://www.liepin.com/zhaopin/?'
# 待爬取的职位
jobs = ['数据挖掘', '图像算法工程师', 'java后端', '互联网产品经理']
# 待爬取的城市,和对应的dqs
citys = ['北京', '上海', '深圳', '广州', '武汉', '杭州']
cityIds = ['010', '020', '050090', '050020', '170020', '070020']
# 构建url
target_url = url+'key='+jobs[0]+'&dqs='+cityIds[0]
# 用get方法爬取数据
getData = requests.get(url=target_url)
# 将获得的数据使用utf-8格式进行转码
finalHtmlData = getData.content.decode("utf-8")
# 预期的输出为爬取到的html内容
# print(finalHtmlData)
regExpUrl = '<a[^>]*href=\"(https://www.liepin.com/job[^"]*)\"[^>]*'
import re
finalAData = re.compile(regExpUrl).findall(finalHtmlData)
for i in finalAData:
print(i)
完整代码的Github仓库地址: FindJobsApp