001.01 一般网页爬虫处理范例
001.01 一般网页爬虫处理范例
#
建檔日期: 2019/07/28
更新日期: 2019/03/28 錯誤更正
Win 10 | Python 3.7.4 |
在这里将不使用 BeatifulSoup 来作网页爬虫,并尽可能不使用其他的库来完成件事,使用别人的库来写程序,好处是简单,快捷,程序码短,而且还不一定要懂内部的细节;但是就因为不懂细节,就很容出错,而且不会真正了解真正的作法等等缺点.
网页爬虫预备动作#
- 打开网页,比如 https://www.51job.com/, 选上方的职位搜索
- 会出现超过十万条的工作信息,我们并不需要这么多资料来供自己处理,因此多加一点条件先行筛选,按下面点选,可以得到较少的数据,比如撰文时的资料有 491 条职位,共分 10 页.
- 检查一下,这十页的网址差异,并建立一份十个网址的 utf-8 格式文本文件 url.txt, 每条网址都有一些参数不同,要自己确认. (如下图)
- 鼠标指向表格中一开始的字段,右键单击选看” 检查元素”, 检查 HTML 内容
- 表格的起始位置及结束位置,并找出表格数据所在的特别的标签或其他可以确认的字符串.
- 找出表格数据所在的特别的标签或其他可以确认的字符串.
- 在此,我们以’<=”el title”>’为表格标题的起点,再找到 > …. < 中的数据,这就是表格的五项标题。后面每一行的数据,则以两个 a title, 三个 span class 为起点,再找到 > …. < 中的数据,这就是表格的一行中的五项数据.
- 注意:不同的系统,浏览器所收到的 HTML 檔会有些差异,比如我的前两笔数据就不是以 a title 为起点,而是以 a target 为起点 其他部份则相同.
- 因此找出这网页的数据步骤为
- 取出 ‘‘ 到 ‘ ‘ 的 HTML
- 找到 ‘<=”el title”>’, 取出’>’和’<’之间表格的五项标题
- 读取每一笔数据
- 找到 ‘a target’, 取出’>’和’<’之间表格的数据,重复两次
- 找到 ‘span class’, 取出’>’和’<’之间表格的数据,重复三次
- 重复以上的动作,读取以下每一笔数据
- 找不到起点的字符串,表示该网页数据已读取完毕,再换下一个网页,直到结束.
程序范例#
import urllib.request
import datetime
# 取现在的时间当作档名
date = datetime.datetime.now()
url_list_file = "url.txt"
data_file_name = "Web Data " + str(date.year) + ("%02d" % date.month) + \
("%02d" % date.day) + ("%02d" % date.hour) + \
("%02d" % date.minute) + ("%02d" % date.second) +".csv"
# 读取网页及存盘用的编码`
decoder = "GB18030"
# 网页中表格的起点及终点
table_format = ['<!--列表表格-->','<!--列表表格 END-->']
area_start = table_format[0]
area_stop = table_format[1]
# 寻找字符串, 并跳过
def find_skip(in_string, string1):
global pointer, string_found
pointer = in_string.find(string1, pointer)
# 确认表格结束
if pointer < 0:
string_found = False
pointer += len(string1)
# 按起始字符串, 读取两个标记中的数据, 标记通常是'>'及'<', 并重复n次
def get_n_data(in_string, string1, string2, string3, n, data_follow):
global pointer, string_found, table
# 重复n次
for i in range(n):
# 跳过起始字符串
find_skip(in_string, string1)
# 表格结束 ?
if string_found:
# 找到第一个标记
find_skip(in_string, string2)
data_start = pointer
# 找到第二个标记
find_skip(in_string, string3)
data_stop = pointer - len(string3)
# 资料放到列表中
data = in_string[data_start : data_stop]
table.append(data.strip())
# 将列表的数据, 按CSV文本文件格式, 写入CSV檔中
def save_table(data_file_name, table):
# 表格是的空的, 不存档
if len(table) != 0:
table_data =""
count = 0
# 表格所有项目转成字符串
for item in table:
count += 1
# 每一行五个数据, 以','间隔, '\n'为结尾
if count != 5:
table_data = table_data+item+','
else:
table_data = table_data+item+'\n'
count = 0
# 建立档案, 写入数据字符串, 档案开闭
datafile = open(data_file_name, 'wt', encoding=decoder)
datafile.write(table_data)
datafile.close()
table =[]
# 读入网址档案中的每一个网址
with open(url_list_file, mode='rt', encoding='utf-8-sig') as url_list:
for url in url_list:
# 解碼读入网页HTML
try:
web_page = urllib.request.urlopen(url.strip())
except urllib.error.URLError:
print('Web page loading failed !!!')
exit()
html = web_page.read().decode(decoder)
# 网页只保留表格部份处理
pointer = 0
data_area_start = html.find(area_start)
data_area_stop = html.find(area_stop)
data_html = html[data_area_start : data_area_stop]
del html
pointer = 0
'''
省略全部表格每一栏的标题, 避免多个页标题和数据混在一起
find_skip(data_html, '<div class="el title">')
get_n_data(data_html, 'span class', '>', '<', 4, ',')
get_n_data(data_html, 'span class', '>', '<', 1, 'n')
'''
# 找不到间隔字符串, 表示表格结束
string_found = True
# 重复取得每一笔的表格数据, 找到起始字中, 再取 >......< 中的资料
while string_found:
# 两次的'a target', '< ......>'的资料
get_n_data(data_html, 'a target', '>', '<', 2, ',')
# 表格结束 ?
if string_found:
# 三次的'span class', '< ......>'的资料
get_n_data(data_html, 'span class', '>', '<', 3, '\n')
# 存表格
save_table(data_file_name, table)
# 结束
exit()
注意:由于本地变量及全局变量的混淆,容易出错,所以我对常用的变量,使用了 Global 定义。确认了一下,程序读入十个网页,取得 491 笔资料,约 34K 档案大小,结果使用了整整 30 秒.
把得到的数据,转存为以”,” 来分隔每一笔资料的.csv 格式檔,用 Excel 外部输入的方式,插到 Excel 中,就可以得到以下近五百笔的数据,至于你要再作什么处理,就看你自己了,比如用 EXCEL 找出职位名有’经理’的部份.
—- The End —
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: