上一节代码如下
import urllib.request
class Spider(object):
def __init__(self):
# 起始页位置
self.begin_page = int(input("请输入起始页:"))
# 终止页位置
self.end_page = int(input("请输入终止页:"))
# 基本 URL
self.base_url = "http://hr.tencent.com/"
def load_page(url):
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"}
for page in range(self.begin_page, self.end_page + 1):
url = self.base_url + "position.php?&start=" + str((page -1)*10 + "#a")
request = urllib.request.Request(url, headers=headers)
# 获取每页 HTML 源代码字符串
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
return html
一、使用正则、lxml、bs4 解析职位数据
在爬取了整个网页之后,下一步就是从整个 HTML 中提取目标数据。
在 Spider 类中,定义一个用于解析网页的方法 parse_page(),分别使用 re 模块、lxml 和 bs4 库进行实现。
① 使用 re 模块解析网页数据
根据前面所分析的网页源代码;
在 HTML 源代码中,职位名称对应的文本位于标签 <a> 中。首先,以 (.*?)</a> 表达式在线测试,匹配到的结果大于预期的10条。由于每个标签 href 属性值的末尾是一样的,可以在表达式的括号前面加上这部分与其它标签进行区分。
lid=0">(.*?)</a>
职位详情链接的文本位于开始标签 <a> 中,且 <a> 中有着唯一的属性,可以与其它 <a> 进行区分。
<a target="_blank" href="(.*?)">
职位类别、招聘人数、地点、发布时间对应的文本都位于开始标签 <td> 和结束标签 </td> 中。
<td>(.*?)</td>
会发现,HTML 的源代码中表格的表头文本也位于 <td> 和 </td> 中,且位于匹配结果的前4个。因此,后期要从这些匹配结果中剔除前4个结果。
② 在 parse_page() 方法中实现
import re
def parse_page(self, html):
"""
定义一个解析网页的方法
html 服务器返回的网页 HTML
"""
# 查找所有的职位名称
names_list = re.findall(r'lid=0">(.*?)</a>', html)
# 查找所有详情链接
links_list = re.findall(r'<a target="_blank" href="(.*?)">', html)
# 查找其它元素
temp_list = re.findall(r'<td>(.*?)</td>)', html)
# 去除表格标题
others_list = temp_list[4:]
# 从 others_list 中截取所有职位类别
category_list = others_list[0::4]
# 从others_list 中截取所有招聘人数
counts_list = others_list[1::4]
# 从 others_list 中截取所有工作地点
location_list = others_list[2::4]
# 从 others_list 中截取所有发布时间
publish_time_list = others_list[3::4]
# 定义空列表,以保存元素的信息
items = []
for i in range(0, len(names_list)):
item = {}
item['职位名称'] = names_list[i]
item['详情链接'] = self.base_url + links_list[i]
item['职位类别'] = category_list[i]
item['招聘人数'] = counts_list[i]
item['工作地点'] = location_list[i]
item['发布时间'] = publish_time_list[i]
items.append(item)
通过观察可以看出,使用正则表达式虽然能解析网页,但是使用起来非常麻烦,一旦网页发生变化,程序很有可能会失效。