import sqlite3, urllib2, re
创建工具类,用于对爬取的结果进行过滤
class DataTool(object):
# 定义查找特殊字符的正则表达式
remove_n = re.compile(r'\n')
# |表示或者
br = re.compile(r'<br>|<br/>')
quot = re.compile(r'"')
def update_res(self, result_tuple):
# result_tuple是用于接收QSBKSpider类传递的数据元组。
name = re.sub(self.remove_n, '', result_tuple[0])
# 首先将段子内容前后两端的\n换行符进行删除
# 然后再将内容中间的<br>标签转化成\n
content = re.sub(self.remove_n, '', result_tuple[1])
content = re.sub(self.br, '\n', content)
content = re.sub(self.quot, '"', content)
# 好评数
vote_number = re.sub(self.remove_n, '', result_tuple[2])
# 评论数
comment_number = re.sub(self.remove_n, '', result_tuple[3])
data_res = (name, content, vote_number, comment_number)
return data_res
创建操作数据库的工具类
class DBManager(object):
connect = None
cursor = None
@classmethod
def db_and_cursor(cls):
cls.connect = sqlite3.connect('qsbk.db')
cls.cursor = cls.connect.cursor()
@classmethod
def insert_data(cls, data_tuple):
insert_sql = "INSERT INTO qsbk (nick_name, content, vote_number, comment_number) VALUES ('%s', '%s', %d, %d)" % (data_tuple[0], data_tuple[1], int(data_tuple[2]), int(data_tuple[3]))
cls.cursor.execute(insert_sql)
cls.connect.commit()
@classmethod
def close_db(cls):
cls.cursor.close()
cls.connect.close()
创建爬虫类
class QSBKSpider(object):
def __init__(self):
self.base_url = "https://www.qiushibaike.com/hot/page/"
# 设置User-Agent
self.headers = {
'User-Agent':"Mozilla/5.0(Windows;U;WindowsNT6.1;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50"
}
# 创建DataTool类的对象,并在__init__()函数中完成对DataTool类的对象引用
self.tool = DataTool()
# 定义获取网页源代码的函数
def get_origin_page_code(self, page_num):
# page_num表示当前页面的页码
abs_url = self.base_url + str(page_num)
# 创建request对象
request = urllib2.Request(abs_url, headers=self.headers)
# 发出请求,获取响应数据
try:
response = urllib2.urlopen(request)
except Exception, e:
print '连接失败,原因是:',e
# 链接失败
return None
else:
# 响应成功,将网页源代码进行返回,交由下一个函数进行数据的提取。
return response.read()
# 定义提取网页数据的函数
def get_info_by_page_code(self, html_string):
# 准备正则表达式
pattern = re.compile(r'<div class="author clearfix">.*?<h2>(.*?)</h2>.*?<div class="content">.*?<span>(.*?)</span>.*?<div class="stats">.*?<i class="number">(.*?)</i>.*?<i class="number">(.*?)</i>', re.S)
results_list = re.findall(pattern, html_string)
for data in results_list:
# 将data元组,传递到DataTool类的函数参数中进行过滤,得到一个新的元组。
res_tuple = self.tool.update_res(data)
# print '昵称:', res_tuple[0]
# print '内容:', res_tuple[1]
# print '好笑数:{}个'.format(res_tuple[2])
# print '评论数:{}个'.format(res_tuple[3])
DBManager.insert_data(res_tuple)
if __name__ == '__main__':
# 链接数据库
DBManager.db_and_cursor()
qsbk_spider = QSBKSpider()
for x in xrange(1,3):
html_string = qsbk_spider.get_origin_page_code(x)
if html_string != None:
qsbk_spider.get_info_by_page_code(html_string)
# 关闭数据库
DBManager.close_db()