准备工作
- 开发工具:pycharm
- python版本:python3
- 用到的类库 re,requests,xlwt
- 可以保存在excel和数据库中
安装这些类库我是借助pip,如果不知道如何用pip请移步到
https://www.jianshu.com/p/7e59f52ea0b6
我们这里以搜索“python”职位为例
爬取数据保存到excel完整代码如下,代码里注释讲解的很清楚了
# -*- coding:utf-8 -*-
import re # 用来做正则匹配用
import requests # 用来做网络请求用
import xlwt # 用来创建excel文档并写入数据
# 要查询的职位
key = 'python'
# 获取原码
def get_content(page):
headers = {'Host': 'search.51job.com',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
url = 'http://search.51job.com/list/000000,000000,0000,00,9,99,' + key + ',2,' + str(
page) + '.html'
r = requests.get(url, headers, timeout=10)
s = requests.session()
s.keep_alive = False
r.encoding = 'gbk'
html = r.text
return html
# 匹配规则
def get(html):
reg = re.compile(
r'class="t1 ">.*? <a target="_blank" title="(.*?)".*? <span class="t2"><a target="_blank" title="(.*?)".*?<span class="t3">(.*?)</span>.*?<span class="t4">(.*?)</span>.*? <span class="t5">(.*?)</span>',
re.S) # 匹配换行符
items = re.findall(reg, html)
return items
def excel_write(items, index):
# 爬取到的内容写入excel表格
for item in items: # 职位信息
for i in range(0, 5):
# print item[i]
ws.write(index, i, item[i]) # 行,列,数据
print(index)
index += 1
newTable = "test.xls" # 表格名称
wb = xlwt.Workbook(encoding='utf-8') # 创建excel文件,声明编码
ws = wb.add_sheet('sheet1') # 创建表格
headData = ['职位', '公司', '地址', '薪资', '日期'] # 表头部信息
for colnum in range(0, 5):
ws.write(0, colnum, headData[colnum], xlwt.easyxf('font: bold on')) # 行,列
# 查询1-10页的数据,这里的10可以改成你想查询多少页
for each in range(1, 2):
index = (each - 1) * 50 + 1
excel_write(get(get_content(each)), index)
wb.save(newTable) # 数据保存到excel表格
运行上面代码控制台输出如下,代表我们成功保存了44条数据。
image.png
再来看下开发工具同目录下多了一个test.xls文件
image.png
打开test.xls文件,可以看到我们成功保存了抓取到的数据到excel文件。这就为我们后期做数据分析打好了准备
image.png
保存到mysql数据完整代码
# -*- coding:utf-8 -*-
import re # 用来做正则匹配用
import requests # 用来做网络请求用
import xlwt # 用来创建excel文档并写入数据
import pymysql # 用来操作数据库
# 要查询的职位
key = 'python'
# 获取原码
def get_content(page):
headers = {'Host': 'search.51job.com',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
url = 'http://search.51job.com/list/000000,000000,0000,00,9,99,' + key + ',2,' + str(
page) + '.html'
r = requests.get(url, headers, timeout=10)
s = requests.session()
s.keep_alive = False
r.encoding = 'gbk'
html = r.text
return html
# 匹配规则
def get(html):
reg = re.compile(
r'class="t1 ">.*? <a target="_blank" title="(.*?)".*? <span class="t2"><a target="_blank" title="(.*?)".*?<span class="t3">(.*?)</span>.*?<span class="t4">(.*?)</span>.*? <span class="t5">(.*?)</span>',
re.S) # 匹配换行符
items = re.findall(reg, html)
return items
# 第一种方式: =============数据存入excel表格
# def excel_write(items, index):
# # 爬取到的内容写入excel表格
# for item in items: # 职位信息
# for i in range(0, 5):
# # print item[i]
# ws.write(index, i, item[i]) # 行,列,数据
# print(index)
# index += 1
#
#
# newTable = "test.xls" # 表格名称
# wb = xlwt.Workbook(encoding='utf-8') # 创建excel文件,声明编码
# ws = wb.add_sheet('sheet1') # 创建表格
# headData = ['职位', '公司', '地址', '薪资', '日期'] # 表头部信息
# for colnum in range(0, 5):
# ws.write(0, colnum, headData[colnum], xlwt.easyxf('font: bold on')) # 行,列
# for each in range(1, 10): # 查询1-10页的数据,这里的10可以改成你想查询多少页
# index = (each - 1) * 50 + 1
# excel_write(get(get_content(each)), index)
# wb.save(newTable) # 数据保存到excel表格
# 第二种方式 =================数据存入数据库
# 操作数据库的类
class MySQLCommand(object):
# 类的初始化
def __init__(self):
self.host = 'localhost'
self.port = 3306 # 端口号
self.user = 'root' # 用户名
self.password = "qcl123" # 密码
self.db = "test" # 库
self.table = "shuju" # 表
# 链接数据库
def connectMysql(self):
try:
self.conn = pymysql.connect(host=self.host, port=self.port, user=self.user,
passwd=self.password, db=self.db, charset='utf8')
self.cursor = self.conn.cursor()
except:
print('connect mysql error.')
# 插入数据,插入之前先查询是否存在,如果存在就不再插入
def insertData(self, my_dict):
table = self.table # 要操作的表格
# 注意,这里查询的sql语句id=' %s '中%s的前后要有空格
sqlExit = "SELECT gongsi FROM " + table + " WHERE gongsi = ' %s '" % (my_dict['gongsi'])
res = self.cursor.execute(sqlExit)
if res: # res为查询到的数据条数如果大于0就代表数据已经存在
print("数据已存在", res)
return 0
# 数据不存在才执行下面的插入操作
try:
cols = ', '.join(my_dict.keys()) # 用,分割
values = '"," '.join(my_dict.values())
sql = "INSERT INTO " + table + " (%s) VALUES (%s)" % (cols, '"' + values + '"')
# 拼装后的sql如下
# INSERT INTO home_list (img_path, url, id, title) VALUES ("https://img.huxiucdn.com.jpg"," https://www.huxiu.com90.html"," 12"," ")
try:
result = self.cursor.execute(sql)
insert_id = self.conn.insert_id() # 插入成功后返回的id
self.conn.commit()
# 判断是否执行成功
if result:
print("插入成功", insert_id)
return insert_id + 1
except pymysql.Error as e:
# 发生错误时回滚
self.conn.rollback()
# 主键唯一,无法插入
if "key 'PRIMARY'" in e.args[1]:
print("数据已存在,未插入数据")
else:
print("插入数据失败,原因 %d: %s" % (e.args[0], e.args[1]))
except pymysql.Error as e:
print("数据库错误,原因%d: %s" % (e.args[0], e.args[1]))
# 查询最后一条数据的id值
def getLastId(self):
sql = "SELECT max(id) FROM " + self.table
try:
self.cursor.execute(sql)
row = self.cursor.fetchone() # 获取查询到的第一条数据
if row[0]:
return row[0] # 返回最后一条数据的id
else:
return 0 # 如果表格为空就返回0
except:
print(sql + ' execute failed.')
def closeMysql(self):
self.cursor.close()
self.conn.close() # 创建数据库操作类的实例
mysqlCommand = MySQLCommand()
mysqlCommand.connectMysql()
def savedb(items, index):
for item in items: # 职位信息
# 只选择长度大于0的结果
if len(item) > 0:
# 这里每次查询数据库中最后一条数据的id,新加的数据每成功插入一条id + 1
dataCount = int(mysqlCommand.getLastId()) + 1
# 职位
try:
zhiwei = item[0]
except Exception:
zhiwei = ""
# 公司
try:
gongsi = item[1]
except Exception:
gongsi = ""
# 地址
try:
dizhi = item[2]
except Exception:
dizhi = ""
# 薪资
try:
xinzi = item[3]
except Exception:
xinzi = ""
# 日期
try:
riqi = item[4]
except Exception:
riqi = ""
# 把爬取到的每条数据组合成一个字典用于数据库数据的插入
news_dict = {
"id": str(dataCount),
"zhiwei": zhiwei,
"gongsi": gongsi,
"dizhi": dizhi,
"xinzi": xinzi,
"riqi": riqi,
}
try:
# 插入数据,如果已经存在就不在重复插入
res = mysqlCommand.insertData(news_dict)
if res:
dataCount = res
except Exception as e:
print("插入数据失败", str(e)) # 输出插入失败的报错语句
for each in range(1, 2): # 查询1-10页的数据,这里的10可以改成你想查询多少页
index = (each - 1) * 50 + 1
savedb(get(get_content(each)), index) # 数据存入mysql数据库
mysqlCommand.closeMysql() # 最后一定要要把数据关闭
dataCount = 0
class MySQLCommand(object):
# 类的初始化
def __init__(self):
self.host = 'localhost'
self.port = 3306 # 端口号
self.user = 'root' # 用户名
self.password = "qcl123" # 密码
self.db = "home" # 库
self.table = "home_list" # 表
# 链接数据库
def connectMysql(self):
try:
self.conn = pymysql.connect(host=self.host, port=self.port, user=self.user,
passwd=self.password, db=self.db, charset='utf8')
self.cursor = self.conn.cursor()
except:
print('connect mysql error.')
# 插入数据,插入之前先查询是否存在,如果存在就不再插入
def insertData(self, my_dict):
table = self.table # 要操作的表格
# 注意,这里查询的sql语句url=' %s '中%s的前后要有空格
sqlExit = "SELECT url FROM " + table + " WHERE url = ' %s '" % (my_dict['url'])
res = self.cursor.execute(sqlExit)
if res: # res为查询到的数据条数如果大于0就代表数据已经存在
print("数据已存在", res)
return 0
# 数据不存在才执行下面的插入操作
try:
cols = ', '.join(my_dict.keys()) # 用,分割
values = '"," '.join(my_dict.values())
sql = "INSERT INTO " + table + " (%s) VALUES (%s)" % (cols, '"' + values + '"')
# 拼装后的sql如下
# INSERT INTO home_list (img_path, url, id, title) VALUES ("https://img.huxiucdn.com.jpg"," https://www.huxiu.com90.html"," 12"," ")
try:
result = self.cursor.execute(sql)
insert_id = self.conn.insert_id() # 插入成功后返回的id
self.conn.commit()
# 判断是否执行成功
if result:
print("插入成功", insert_id)
return insert_id + 1
except pymysql.Error as e:
# 发生错误时回滚
self.conn.rollback()
# 主键唯一,无法插入
if "key 'PRIMARY'" in e.args[1]:
print("数据已存在,未插入数据")
else:
print("插入数据失败,原因 %d: %s" % (e.args[0], e.args[1]))
except pymysql.Error as e:
print("数据库错误,原因%d: %s" % (e.args[0], e.args[1]))
# 查询最后一条数据的id值
def getLastId(self):
sql = "SELECT max(id) FROM " + self.table
try:
self.cursor.execute(sql)
row = self.cursor.fetchone() # 获取查询到的第一条数据
if row[0]:
return row[0] # 返回最后一条数据的id
else:
return 0 # 如果表格为空就返回0
except:
print(sql + ' execute failed.')
def closeMysql(self):
self.cursor.close()
self.conn.close() # 创建数据库操作类的实例
保存到数据库的数据如下
image.png
到这里就实现了python爬虫功能
网友评论