先统一引入本次爬取信息所需要的库文件
from bs4 import BeautifulSoup # 网页解析,获取数据
import re # 正则表达式,进行文字匹配
import urllib.request, urllib.error # 制定url,获取网页数据
import sqlite3 # 进行SQLite数据库操作
URL的网页内容:通过在headers里面添加相关信息,以此来达到代码模拟浏览器向服务器发送的信息的目的
# URL的网页内容
def askURL(url):
# 模拟浏览器头部信息,向服务器发送消息
head = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.34"
} # 用户代理:表示告诉目标服务器,我们是什么类型的机器;浏览器:本质上告诉服务器,我们能够接受什么水平的内容
request = urllib.request.Request(url, headers=head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
# print(html)
except urllib.error.URLError as e:
if hasattr(e, "code"):
print(e.code)
if hasattr(e, "reason"):
print(e.reason)
return html
这里需要注意不同的网页的编码格式有可能不同,例如:‘utf-8’,‘gb2312’等相关类型
爬取网页
原始地址
选择不同队进行跳转
通过观察目标网址,当我们选择不同球队时,目标网址会在之前的网址前加上对应球队的英文名,以此来进行网页的跳转
def main():
baseurl = "https://nba.hupu.com/players/"
# 1、爬取网页
datalist = getData(baseurl)
因此当我们需要爬取所有球队的全部球员时,只需要将所有队名放入在一个列表中,然后使用一个for循环对列表进行遍历,然后与原始URL进行拼接,以此来达到访问所有球队球员的目的
def getData(baseurl):
datalist = []
teamslist = ['grizzlies','mavericks','spurs','rockets','pelicans','warriors','suns','clippers','lakers',
'jazz','nuggets','timberwolves','blazers','thunder','nets','76ers','celtics','raptors','knicks',
'heat','wizards','hornets','hawks','magic','bulls','bucks','cavaliers','pacers','pistons']
# teamslist = ['grizzlies']
for i in teamslist:
url = baseurl + str(i)
html = askURL(url)
网页解析
目前就可以拿取到所有球队的网页源码(部分示例)
当我们拿到网页源码之后,对其进行分析,根据我们需要拿到的数据使用正则表达式和BeaytifulSoup相关规则进行提取
正则表达式代码示例:
# 获取球员详情数据的正则表达式规则
#球员图片
findImgSrc = re.compile(r'<img src="(.*?)"')
# 球员号码
findNum = re.compile(r'<td>(\d{1,2})</td>')
# 球员位置
findPosition = re.compile(r'<td>([A-Z-]+)</td>')
# 球员身高
findHeight = re.compile(r'<td>(.*?米/.*?)</td>')
# 球员体重
findWeight = re.compile(r'<td>(.*?公斤/.*?)</td>')
# 球员出生日期
findBirth = re.compile(r'<td>(\d{4}-\d{1,2}-\d{1,2})</td>')
# 球员薪资
findSalary = re.compile(r'<b>(本年薪金\:.*)</b>')
页面解析示例代码:
# 2、逐一解析数据
soup = BeautifulSoup(html, "html.parser")
for item in soup.find_all('table', class_="players_table"): # 查找符合要求的字符串,形成列表
print(item) #测试:查看球员item全部信息
data = [] # 保存每一位球员的所有信息
item = str(item)
# 获取到球员详情的链接
link = []
linkHtmllist = soup.find_all("td", class_="td_padding") #使用bs4获取链接
for linkHtmls in linkHtmllist:
link.append(linkHtmls.find('a').get('href'))
# print(link)
data.append(link) # 添加链接
imgSrc = re.findall(findImgSrc, item)
data.append(imgSrc) # 添加图片
names = []
nameHtmls = soup. select("td[class='left']>b>a")
for nameHtml in nameHtmls:
names.append(nameHtml.text)
# print(names)
data.append(names) #添加姓名
num = []
numlist = re.findall(findNum, item)
for nums in numlist:
#print(num)
num.append(nums)
# print(num)
data.append(num) # 添加号码
position = []
positionlist = re.findall(findPosition, item)
for positions in positionlist:
# print(position)
position.append(positions)
# print(position)
data.append(position) # 添加位置
height = []
heightlist = re.findall(findHeight,item)
for heights in heightlist:
#print(height)
height.append(heights)
data.append(height) # 添加身高
weight = []
weightlist = re.findall(findWeight,item)
for weights in weightlist:
#print(weight)
weight.append(weights)
data.append(weight) # 添加体重
birth = []
birthlist = re.findall(findBirth,item)
for births in birthlist:
#print(birth)
birth.append(births)
data.append(birth) # 添加出生日期
salary = []
salarylist = re.findall(findSalary,item)
for salarys in salarylist:
#print(salary)
salary.append(salarys)
# print(salary)
sala = []
sa = []
for str1 in salary:
str2 = str1.split(':')[1]
money = str2.replace('万美元','')
sala.append(money)
for str4 in sala:
if str4 == '':
str4 = '0'
sa.append(str4)
data.append(sa) # 添加本年薪金
print(data)
此时我们爬取下来的数据是每一类放置在一个列表中
因为我们后面需要将爬取到的数据放置在数据库中,我们需要按照一个球员一个列表的形式进行存储,所以利用循环将每一个球员的信息遍历出来
for d in range(len(data[0])):
l =[]
for s in range(len(data)):
l.append(data[s][d])
datalist.append(l) # 把处理好的信息放入datalist
打印结果
到达这个阶段我们已经将所需要的信息爬取整理完毕,接下来就是存储到数据库中
使用sql语句创建数据表
def init_db(dbpath):
sql = '''
create table players
(
id integer primary key autoincrement,
info_link text,
pic_link text,
name varchar,
num int,
position varchar ,
height varchar ,
weight varchar ,
birth datatime,
salary text
)
''' # 创建数据表
conn = sqlite3.connect(dbpath)
cursor = conn.cursor() # 创建游标
cursor.execute(sql) # 执行sql语句
conn.commit()
conn.close() # 关闭连接
数据存储
# 保存数据
def saveData(datalist, dbpath):
print("数据保存中...")
init_db(dbpath)
conn = sqlite3.connect(dbpath)
cur = conn.cursor()
for data in datalist:
for index in range(len(data)):
data[index] = '"' + data[index] + '"'
sql = '''
insert into players(
info_link,pic_link,name,num,position,height,weight,birth,salary)
values(%s)''' % ",".join(data)
# print(sql)
cur.execute(sql)
conn.commit()
cur.close()
conn.close()
print("保存数据成功!")
数据库中