1. 首先,引入要用到的包,代码如下:
from urllib import request
import re
import sqlite3
from tools import StrTools
2. 代码中需要声明的类、类中的属性以及定义的功能函数如下:
"""
类名: QsbkSpider
属性: url 地址
html 网页源代码
headers 请求头
conn 数据库连接
cursor 数据库游标
函数: connect_sql() 连接数据库
close_sql() 关闭数据库
create_table() 创建数据表
get_html() 获取网页源代码
parse_html() 解析网页源代码,提取数据
save_data() 保存数据
get_next_link() 获取下一页链接
run()启动程序
"""
3. 具体功能代码如下:
class QsbkSpider(object):
def __init__(self):
self.url = 'https://www.qiushibaike.com/hot/'
self.html = ''
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0'
}
self.conn = None
self.cursor = None
self.create_table()
def connect_sql(self):
"""连接数据库"""
self.conn = sqlite3.connect('sqbk.db')
self.cursor = self.conn.cursor()
def close_sql(self):
"""关闭数据库"""
self.conn.commit()
self.cursor.close()
self.conn.close()
def create_table(self):
# 1.链接数据库
self.connect_sql()
# 2.准备创建表的sql语句
sql = 'CREATE TABLE IF NOT EXISTS qsbk(id INTEGER PRIMARY KEY, author CHAR, age INTEGER ,content TEXT, simle_num INTEGER ,comments INTEGER)'
# 3.执行sql
self.cursor.execute(sql)
# 4.关闭
self.close_sql()
def get_html(self):
"""构建请求,发送请求,接收响应数据"""
req = request.Request(url=self.url, headers=self.headers)
response = request.urlopen(req)
# 将返回的数据读取并转换为字符串,赋值给对象的html属性
self.html = response.read().decode('utf-8')
def parse_html(self):
"""准备正则,提取网页数据"""
pattern = re.compile(r'<h2>(.*?)</h2>.*?<div class="articleGender.*?>(.*?)</div.*?<div class="content".*?<span>(.*?)</span>.*?<i class="number">(.*?)</i.*?<i class="number">(.*?)</i>', re.S)
results = re.findall(pattern, self.html)
for r in results:
# 处理字符串
author = StrTools.process_str(r[0])
age = r[1]
content = StrTools.process_str(r[2])
smile_num = r[3]
comments = r[4]
self.save_data(author, age, content, smile_num, comments)
def save_data(self, *args):
"""保存数据"""
# 1.连接数据库
self.connect_sql()
# 2.准备sql语句
sql = "INSERT INTO qsbk(author,age,content,smile_num,comments)VALUES('%s',%s,'%s',%s,%s)" % args
# 3.执行sql
self.cursor.execute(sql)
# 4.关闭
self.close_sql()
def get_next_link(self):
"""
获取下一页链接"
:return: True 表示找到下一页,可以继续执行循环 False表示没有找到下一页,可以结束循环
"""""
# 1.找到ul标签部分的html代码
pattern = re.compile(r'<ul class="pagination".*?</ul>', re.S)
res = re.search(pattern, self.html)
# 若找到
if res:
ul_html = res.group()
links = re.findall(re.compile(r'<li.*?<a href="(.*?)"', re.S), ul_html)
if 'page' in links[-1]:
# 拼接下一页完整地址
self.url = 'https://www.qiushibaike.com' + links[-1]
return True
else:
return False
else:
return False
def run(self):
count = 0
while True:
self.get_html()
count += 1
print('正在爬取第%s页数据,请稍后.....' % count)
self.parse_html()
print('第%s页数据爬取完成,已入库!' % count)
is_next = self.get_next_link()
if not is_next:
print('数据爬取完毕,已存入数据库中!')
break
if __name__ == '__main__':
qsbk = QsbkSpider()
qsbk.run()