课纲
一、乘法表与文件操作
我只想说,我学会遍历文件结构,并轻松提取文件目录并批量写入内容
#导入OS模块
import os
#待搜索的目录路径
path = "Day1-homework"
#待搜索的名称
filename = "2020"
#定义保存结果的数组
result = []
import re
def findfiles():
#在这里写下您的查找文件代码吧!
for root, dirs, files in os.walk(path):
# print('root: ',root) #当前目录路径
# print('dirs: ',dirs) #当前路径下所有子目录
# print('files: ',files) #当前路径下所有非目录子文件
for f in files:
if filename in f:
result.append(os.path.join(root,f))
for index,name in enumerate(result):
print('第{}个文件,文件名是:{}'.format(index+1,name))
if __name__ == '__main__':
findfiles()
二、层级页面爬虫
此处的精妙之处在于,定位特定表格位置,然后通过表格里link发散寻找。
import json
import re
import requests
import datetime
from bs4 import BeautifulSoup
import os
#获取当天的日期,并进行格式化,用于后面文件命名,格式:20200420
today = datetime.date.today().strftime('%Y%m%d')
def crawl_wiki_data():
"""
爬取百度百科中《青春有你2》中参赛选手信息,返回html
"""
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
url='https://baike.baidu.com/item/青春有你第二季'
try:
response = requests.get(url,headers=headers)
print(response.status_code)
#将一段文档传入BeautifulSoup的构造方法,就能得到一个文档的对象, 可以传入一段字符串
soup = BeautifulSoup(response.text,'lxml')
#返回的是class为table-view log-set-param的<table>所有标签
tables = soup.find_all('table',{'class':'table-view log-set-param'})
crawl_table_title = "参赛学员"
for table in tables:
#对当前节点前面的标签和字符串进行查找 #找到参赛学员那一栏的数据
table_titles = table.find_previous('div').find_all('h3') #前一个节点是h3
for title in table_titles:
if(crawl_table_title in title):
return table
except Exception as e:
print(e)
找图片分连接
def crawl_pic_urls():
'''
爬取每个选手的百度百科图片,并保存
'''
with open('work/'+ today + '.json', 'r', encoding='UTF-8') as file:
json_array = json.loads(file.read())
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
pic_urls=[]
public_url='https://baike.baidu.com'
for star in json_array:
name = star['name'] #总共109个人
link = star['link']
#!!!请在以下完成对每个选手图片的爬取,将所有图片url存储在一个列表pic_urls中!!!
response = requests.get(link,headers=headers)
soup = BeautifulSoup(response.text,'lxml')
pic_list_url=soup.select('.summary-pic a')[0].get('href')
pic_list_url=public_url+pic_list_url
#向选手图片列表页面发送http get请求
pic_list_response=requests.get(pic_list_url,headers=headers)
bs=BeautifulSoup(pic_list_response.text,'lxml')
pic_list_html=bs.select('.pic-list img')
pic_urls=[]
for pic_html in pic_list_html:
pic_url=pic_html.get('src')
if 'resize'in pic_url:
pic_url=pic_url.split('?')[0] #确保下载的是原图。
pic_urls.append(pic_url)
# # #!!!根据图片链接列表pic_urls, 下载所有图片,保存在以name命名的文件夹中!!!
down_pic(name,pic_urls)
三、数据可视化
此处精妙之处在于如何导入数据到图表容器里面
import matplotlib.pyplot as plt
import numpy as np
import json
import matplotlib.font_manager as font_manager
import os
#显示matplotlib生成的图形
%matplotlib inline
with open('data/data31557/20200422.json', 'r', encoding='UTF-8') as file:
json_array = json.loads(file.read())
#绘制小姐姐区域分布柱状图,x轴为地区,y轴为该区域的小姐姐数量
zones = []
for star in json_array:
zone = star['zone']
zones.append(zone)
print(len(zones))
print('zones: ',zones)
zone_list = []
count_list = []
for zone in zones:
if zone not in zone_list:
count = zones.count(zone)
zone_list.append(zone)
count_list.append(count)
print('zone_list: ',zone_list)
print('count_list: ',count_list)
if not os.path.exists('/home/aistudio/work/result'):
os.makedirs('/home/aistudio/work/result')
# 设置显示中文
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
plt.figure(figsize=(20,15))
plt.bar(range(len(count_list)), count_list,color='r',tick_label=zone_list,facecolor='#9999ff',edgecolor='white')
#这里很关键,tick_label就是X轴数据,count_list是y轴数据
# 这里是调节横坐标的倾斜度,rotation是度数,以及设置刻度字体大小
plt.xticks(rotation=45,fontsize=20)
plt.yticks(fontsize=20)
plt.legend()
plt.title('''《青春有你2》参赛选手''',fontsize = 24)
plt.savefig('/home/aistudio/work/result/bar_result.jpg')
plt.show()
这里很关键,tick_label就是X轴数据,count_list是y轴数据
四、图像样本生成自制数据集标签文本,以及finetune
此处精妙之处是与Day01相呼应,唯一难搞的是喂入模型的数据路径不能错
import os
filepath1='dataset/file'
filepath2='dataset/test'
result=[] #存储图片路径
#路径还是需要调整一下 file里面的文件需要取出
def findfile(filepath):
for root,dirs,files in os.walk(filepath):
for file in files:
result.append(os.path.join(root,file))
return result
def createRecord(result):
record=[]
for s in result:
#s是子路径
name=s.split('/')[2]
s=s.replace('dataset/','')
if '虞书欣' in name:
record.append(s+' '+'0')
elif '许佳琪'in name:
record.append(s+' '+'1')
elif '赵小棠' in name:
record.append(s+' '+'2')
elif '安崎' in name:
record.append(s+' '+'3')
elif '王承渲'in name:
record.append(s+' '+'4')
return (record)
def writefile(result,filepath):
for r in result:
with open(filepath,'a',encoding='utf-8') as f:
f.write(r+'\r\n')
result=findfile(filepath1)
record=createRecord(result)
writefile(record,'dataset/train_list.txt')
五、瀑布流评论爬取、数据清洗、分词、可视化以及文本分析
此处大作业最为精华是评论规律的寻找。我们知道瀑布流它在一个页面是中需要通过JS脚本来引导不同的数据流的生成与隐藏,那么需要找到瀑布翻滚点,才能找到切入位置。而评论的翻滚点恰恰就是通过分析URL里面得出
last_id就是翻滚点,last_id就是一个页面的最后一个用户的评论id,然后触发JS,以这个最后用户为请求点向服务器发起请求,从而返回新的瀑布,更新当前的数据流。
所以此处借鉴了数据结构算法里面费波拉契数列迭代的思想,来进行lastid的迭代。而迭代次数=页数
def getMovieinfo(page):
#创建url+ 迭代更新含义新的last_id的url
#返回response
# url='https://www.iqiyi.com/v_19ryfkiv8w.html#curid=15068699100_9f9bab7e0d1e30c494622af777f4ba39' #总的url
contents=[]
last_id='240986405821'
#首次出现的评论url,以此为基础
url='https://sns-comment.iqiyi.com/v3/comment/get_comments.action?agent_type=118&agent_version=9.11.5&authcookie=68ejvC2i5Bv27zId46WDscOfR08wtOFTp38W0gRL2Num33WFxnkukwxoZB1VRNYeSdC06&business_type=17&content_id=15068699100&hot_size=0&last_id={}&page=&page_size=40&types=time&callback=jsonp_1587947716356_24488'.format(last_id)
part1Url='https://sns-comment.iqiyi.com/v3/comment/get_comments.action?agent_type=118&agent_version=9.11.5&authcookie=68ejvC2i5Bv27zId46WDscOfR08wtOFTp38W0gRL2Num33WFxnkukwxoZB1VRNYeSdC06&business_type=17&content_id=15068699100&hot_size=0&last_id='
part2Url='&page=&page_size=40&types=time&callback=jsonp_1587947716356_24488'
i=0
while i<page: #控制迭代的出口
#这里是拼接url加存储contents
time.sleep(1) #防止暴力爬虫
new_last_id,content=saveMovieInfoToFile(url) #迭代点
contents+=content
url=part1Url+new_last_id+part2Url
i+=1
print('正在爬取第{}页'.format(str(i)))
print('共收集了{}条评论'.format(len(contents)))
return contents #全部的评论信息
def saveMovieInfoToFile(url):
#解析页面获取lastid
# 解析json数据,获取评论
# 参数 lastId:最后一条评论ID arr:存放文本的list
sub_content=[]
headers={'User-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400'}
RawData=requests.get(url,headers=headers).text
callback=callback=url.split('callback=')[1]
RawData=RawData.replace('try{','').replace(' '+callback+'(','').replace('catch(e){};','').replace('})','')
JsonData=json.loads(RawData)
obj_data=JsonData['data']['comments']
for obj in obj_data:
#防止出现有用户没有发送评论而没有产生content
try:
sub_content.append(obj['content']) #获取原生评论,把清洗的部分放后面,防止由于清洗规则,影响结果
last_id=obj['id']
except:
last_id=obj['id']
return last_id,sub_content #每一页的评论信息以及最后一个lastid
心得
我觉得这次的训练营非常适合我这种半吊子的小白,可以很好的把之前零零碎碎的知识串起来,也体验了finetune的好玩之处。觉得这课堂没有白来。也认识了大神“我三岁”,希望能交到更多朋友,抱团取暖,才会走得更远。现在框架这么多,我觉得大家不应该互相排斥,互相嫌弃,交流使得你获得提升,开放的心态才能让你获得更好的动力。如果一味只是抱着你仅存的那点知识与优越感,看到别人在问的时候不言不语,那样只会使得自己的知识得不到流通与提升。
题外话:
你知道fine tune的精髓是什么吗,是在于它的鲁棒性与扩展性,我已经学会了原有的知识与权重,如果我不拿出来finetune,我所知道的权重将无法提升鲁棒性,那么随着多任务的场景接入,难道我还要重新训练权重吗,然后又死循环回21天超神的谎言里面,然后顺带买VIP什么的。我觉得要打破这种死坑,除了自己内力不断提升,还需要交流,才不会被坑更多的冤枉钱。