20212313 吳劍標 實驗四 Python綜合實踐實驗報告
阿新 • • 發佈:2022-05-24
課程: 《Python程式設計》
班級: 2123
姓名: 吳劍標
學號: 20212313
實驗教師: 王志強
實驗日期: 2022年5月25日
必修/選修: 公選課
一、實驗內容
1、實驗靈感與設計
最初的想法,因為我這個酷愛閱讀小說,然後最近又學習的python的爬蟲技術,所以靈光凸顯,想著做一個爬取小說網站的實驗吧。但因為我認為單單隻有爬取網站的實驗重複性太高了,基於我上學期學習了tkinter的圖形使用者介面,就想著可以直接做一個頁面來爬取小說排行榜以及小說的章節還有小說的內容。
2、實驗過程與結果
前期的準備:
(1)確定的大致的實驗方向後,我就開始了技術準備,先複習了一下上學期的tkinter,還有加強學習這學期的request以及beautifulsoup還有lxml模組。
(2)並且選擇了爬取的小說網站:https://wap.xbiquge.la/
編寫python
1、開頭先爬取小說頁面的小說名並且將其儲存再檔案中。
import requests import re import distutils.sysconfig from lxml import etree from bs4 import BeautifulSoup import string url = "https://www.xbiquge.la/xiaoshuodaquan/" response = requests.get(url) response.encoding="utf-8" html = response.text ele = etree.HTML(html) book_names = ele.xpath("//div[@id='main']/div[@class='novellist']/ul/li/a/text()") book_urls = ele.xpath("//div[@id='main']/div[@class='novellist']/ul/li/a/@href") s = '' for book_name in range(len(book_names)): s += book_names[book_name] + '\n' + book_urls[book_name] + '\n' with open('title.txt','w+') as file: file.writelines(s)
2、建立tkinter的圖形使用者介面
import tkinter root=tkinter.Tk() root.title("爬取小說") root.geometry('1250x700') root.resizable lable1=tkinter.Label(root,text='開始爬取小說吧!',width='30',height='1',font=22).grid(row=1,column=1) text1=tkinter.Text(root,width=30,height=40) text1.grid(row=3,column=1) def button1(): text1.insert("end",s) button1=tkinter.Button(root,text="爬取目錄",command=button1,width=30,height=2).grid(row=2,column=1) lable=tkinter.Label(root,text="一共有3000本書供您閱讀",width=30,height=1,font=22).grid(row=4,column=1) lable2=tkinter.Label(root,text='輸入你想要閱讀的小說的連結',width='40',height='1',font=22).grid(row=1,column=2) text2=tkinter.Text(root,width=40,height=2) text2.grid(row=2,column=2) bookname=text2.get("1.0","end") text3=tkinter.Text(root,width=40,height=40) text3.grid(row=3,column=2) button2=tkinter.Button(root,text="爬取書的章節" ,command=button2,width=15,height=2).grid(row=2,column=3) lable3=tkinter.Label(root,text='請在下面的文字框輸入你想要閱讀的小說的連結',width='50',height='1',font=22).grid(row=1,column=4) text4=tkinter.Text(root,width=50,height=2) text4.grid(row=2,column=4) text5=tkinter.Text(root,width=50,height=40) text5.grid(row=3,column=4) root.mainloop()
3、編寫爬取小說章節和小說內容的函式來運用到tkinter的button中去
def papuzhangjie(c):
response1 = requests.get(url=c)
response1.encoding = "utf-8"
html1 = response1.text
ele1 = etree.HTML(html1)
book_chapters = ele1.xpath("//div[@class='box_con']/div[@id='list']/dl/dd/a/text()")
book_c_urls = ele1.xpath("//div[@class='box_con']/div[@id='list']/dl/dd/a/@href")
print(len(book_chapters))
s1 = ""
for book_chapter in range(len(book_chapters)):
s1 += book_chapters[book_chapter] + "\n" + 'https://www.xbiquge.la'+book_c_urls[book_chapter] + "\n"
with open('chapter.txt', 'w+') as file1:
file1.writelines(s1)
print("輸入成功")
return s1```
```def xiaoshuoneirong(d):
def remove_upprintable_chars(s):
"""移除所有不可見字元"""
return ''.join(x for x in s if x.isprintable())
# new_url = o_url + chapter_urls[0]
response = requests.get(d)
response.encoding = "utf-8"
html = response.text
# print(html)
ele = etree.HTML(html)
book_bodys = ele.xpath("//div[@id='content']/text()")
# print(book_bodys[0])
#s = "\n" + chapter_titles[i] + "\n"
s2=" "
for book_body in book_bodys:
c = "".join(book_body.split())
#c = remove_upprintable_chars(c)
s2 += c
with open('neirong.txt','w+') as file3:
file3.writelines(s2)
return s2
def button1():
text1.insert("end",s)
def button2():
c=str(text2.get("1.0","end"))
zhangjie=papuzhangjie(c)
#print(zhangjie)
text3.insert("end",zhangjie)
4、最終整合起來,形成了最終的實驗結果
5、上傳ECS,並使用
6、實驗反思與感想
本次實驗是歷時最長,難度最大的一次了。前前後後花了好多時間學習。
遇到的困難:
(1).上學期學習的tkinter已經大部分忘記,複習起來很有難度。
(2).再html中很難的爬取準確且需要的內容。我剛開始是一頭霧水,最終通過學習lxml中的xpath最後才能勉強爬取所需內容,但難度依舊很大,很容易出錯。
(3).tkinter 的text和lable和button的排版比較複雜,所以最終的實驗結果也沒有將其頁面做的好看,結果頁面太過簡單。
(4).講爬取小說內容和小說章節的函式與button的command結合起來,是我第二頭疼的地方。
二、課程總結
1、課程筆記(都是以pycharm的形式記錄的)
python筆記
import base64
def make_skirt(chima,yinzi):
print(f'您要定製的skirt尺碼是{chima},印字是{yinzi}')
make_skirt('xl',yinzi='hahah勒布朗')
def city(cityname,county='中國'):
print(f'{cityname}is in {county}')
city('shanghai')
city('beijing')
city('lundong','england')
name1=["wjb","jzj","gy","hhl"]
def dictionary(name):
a=name1.append(name)
return a
dictionary('llc')
dictionary('cpy')
print(name1)
a={'name':'wjb','singer':'llc','number':'10'}
print(a)
def make_album(name3,singer,number=None) :
if number:
a={'name':{name3},'singer':{singer},'number':{number}}
else :
a = {'name': {name3}, 'singer': {singer}}
return a
b=make_album('jzj','sb',10)
c=make_album('lbj','fw',10)
d=make_album('czy','zz')
print(a)
print(c)
string1="zzzzz20212313"
number=string1[5:14] #分割
print(number)
#spilt ("#",3) 這個是以#分割三次的意思
#string1.find("#") 是查詢有多少個警號
#strip 是去掉字元
#正則表示式: ^是開始的意思,$是結束的意思333333
#\w是匹配字母數字或下劃線或漢字,不能匹配\
#^\d{8,11}$ 表達是匹配八-11位的數字
#go*gle 匹配gglr到gooole *是匹配前面的字元0次以上 ?是匹配0次或一次
#go+gle 匹配gogle到goooooole +是匹配前面的字元1次以上
# | 是或的意思
import re #引入正則運算
pattern= '^(13[4-9]\d{8})$'
mobile ='11560665795'
pipei=re.match(pattern,mobile)
print(pipei)
if pipei==None:
print("no")
else:
print("yes")
"""
a=int(input("輸入人數:"))
sum=0
for i in range (0,a):
b = int(input("輸入站數:"))
if b>=1 and b<=4 :
price=3
elif b>=5 and b<=9:
price=4
elif b>=10:
price=5
print(f'''應付款{price}''')
sum=sum+price
print(f'''應付款總額為{sum}''')
"""
class User():
def __init__(self,name,login_attempts):
self.login_attempts=login_attempts
self.name=name
def increment_login_attempts(self):
login_attempts =self.login_attempts +1
print(login_attempts)
def reset_login_attempts(self):
login_attempts=0
print(login_attempts)
wjb=User('llc','4')
class Student:
def __init__(self, name, number):
self.name = name
self.number = number
def student_info(self):
print('name: {}, number: {}'.format(self.name, self.number))
student = Student('zhang', 34)
student.student_info()
print(student.__dict__)
import random
import string
a=random.sample(string.digits,4)
print(a)
print(a[::-1])
print(".".join(a))
# class裡面是屬性(形參)加方法(def)
#具體的name如wjb,這個是例項,引用例項是用.
class people :
pi=3.1415926 #__是封裝,只能在類中被使用
__llc=wjb
def __init__(self,name,number):
self.name=name
self.number=number
def put_npy(self):
print("lalalalal")
s=people("llc","20211111")
print(s.name,s.number)
print(s.put_npy())
print(people.pi)
#類中最重要的是封裝繼承多型
# __雙下劃線是封裝。只能在類中被使用。
#多型就是一個類中可以有多個子類,且不同子類可以有同種例項方法,如都有def hobby()
'''import json
filename='username.json'
username=input("輸入使用者名稱")
with open(filename,'r+') as f:
json.dump(username,f) #檔案拓展名一定要是json
print("存入使用者名稱成功")
with open(filename, 'r+') as f:
name=json.load(f)
print(f'歡迎回來,{name}')
'''
'''
socket是用於連線兩個埠的。網路程序都是通過socket通訊
s.bind(address) 繫結ip地址
s.listen
'''
import socket
a=socket.gethostname() #獲取主機名
b=socket.gethostbyname(a)#通過解析主機名得出ip地址
print(b)
print(socket.getservbyname('http')) #搜尋埠的
#sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #建立tcp的socket ,第一個是用於伺服器與伺服器之間的網路通訊,第二個是基於TCP的流式socket通訊。
#s.bind(b,5050)
#s.listen
'''while True:
conn,addr=s.accept()
print(addr)
while True:
data=conn.recv()
print(data)
conn.send("server received you message.")'''
s=lambda a,b:a+b
print(s([2],[3,4]))
print(s(3,5))
a="llala798 wjb很聰明"
b=a.encode('utf-8')
print(a)
print(b)
print(b.decode()) #把中文編碼
print(bytes(a,'utf-8'))
c=base64.b32encode(bytes(a,'utf-8'))
print(c)
print(base64.b32decode(c).decode())
#bytes(a,'utf-8')=a.encode(utf-8)=
with open('llc.txt','r+',encoding='utf-8') as f:
print(bytes(f.read(),'utf-8'))
import os
'''
檔案讀寫:
r是隻讀,檔案必需存在
r+是可以讀也可以全覆蓋
w是隻寫,可以建立新檔案
w+是開啟後清空檔案內容然後可讀可寫
a是在檔案末尾追加
a+是在檔案末尾寫,或者是建立新檔案
os 模組
getcwd() 是顯示當前目錄
mkdir 是建立目錄
rmdir 刪除目錄
'''
path=r"C:\Users\26233\Desktop"
if os.path.exists(path):
print("路徑存在")
else:
os.mkdir(path)
with open(path+"\\學習成績.txt","a+") as file1:
#name=input("輸入你的名字")
#number=input("輸入你的學號")
#score=input("輸入你的成績")
#file1.write(f'''姓名:{name}\n學號:{number}\n你的成績:{score}\n''')
file1.seek(0) #如果沒有seek,寫入後指標指向末尾[EOF],因此讀出空
student1=file1.read()
print(student1)
#隨機生成姓名和性別和學號
import requests
from bs4 import BeautifulSoup
import lxml
url=r"https://www.baidu.com/s" #要爬蟲的地址
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 Safari/537.36 SE 2.X MetaSr 1.0'} #標頭檔案
response=requests.get(url='https://www.besti.edu.cn/')
soup1=BeautifulSoup(response.content,'lxml')
print(soup1.title)
print(soup1.name)
#print(soup1)
e = requests.get('https://www.bilibili.com/v/popular/rank/game') #當前網站連結
soup2 = BeautifulSoup(e.content,'lxml') #解析html
print(soup2.title)
div_people_list = soup2.find('ul', attrs={'class': 'rank-list'}) #爬取ul類class為rank-list下的資料
print(div_people_list)
ca_s = div_people_list.find_all('a', attrs={'class': 'title'}) #爬取a類class為title下的資料
print(ca_s)
2、結課感謝
> 選課之前,我對python課程設計是抱著繼續進步的心態的。這學期的課程,我認為讓我在python的基礎內容是有了更夯實的基礎,並且也讓我擴寬了知識面,如正則表示式還有python中的爬蟲,還有socket等等。都讓我受益匪淺。我想繼續努力。提高自己的python技能水平。我的下學期學習目標是,學習好pygame和 wxpython。
> 最後希望有時間還可以繼續請教老師,大家都一起努力進步