From e8af5495ec07d279bff71f359e702979a5f9cd7a Mon Sep 17 00:00:00 2001 From: snowball <851317190@qq.com> Date: Tue, 14 Dec 2021 20:30:05 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=97=A5=E5=BF=97=E6=96=87=E4=BB=B6=E5=92=8C?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E8=A1=A8=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 7 +++-- request.py | 13 +++++---- tools.py | 81 ++++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 80 insertions(+), 21 deletions(-) diff --git a/main.py b/main.py index 85de0d3..03645fc 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,10 @@ import request -import time +import tools as t req = request.Request() -status = req.get(url="https://movie.douban.com/top250", start=25) + +page = t.Utils.choosePage(page_number=1) # page_number:参数取值范围1~10, 默认为第一页 + +status = req.get(url="https://movie.douban.com/top250", page=page) save_path = ".\\data\\filmData.xls" if status: req.do(path=save_path) diff --git a/request.py b/request.py index bbf6f52..91d776d 100644 --- a/request.py +++ b/request.py @@ -4,17 +4,18 @@ import xlrd import time + class Request: # 类成员html html = '' - def get(self, url, start): + def get(self, url, page): # 模拟http头文件信息 head = { "USER-Agent": 'Mozilla / 5.0(Windows NT 10.0; Win64; x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome ' '/ 80.0.3987.122 Safari / 537.36 ' } - url = url + '?start=' + str(start) # 组装url地址 + url = url + '?start=' + str(page) # 组装url地址 html = requests.get(url, timeout=30, headers=head) html.encoding = 'utf-8' if html.status_code != 200: @@ -25,10 +26,10 @@ def get(self, url, start): def do(self, path): obj = t.DataResolve(html=self.html) # 实例化DataResolve对象 - print("*"*20, "解析执行开始", "*"*20) + print("*" * 20, "解析执行开始", "*" * 20) result = obj.resolve() # 执行解析 time.sleep(0.1) - print("*"*20, "解析结束", "*"*20) + print("*" * 20, result, "*" * 20) workbook = xlrd.open_workbook(path) sheets_name = workbook.sheet_names() sheet = workbook.sheet_by_name(sheet_name=sheets_name[0]) @@ -46,5 +47,7 @@ def do(self, path): time.sleep(0.1) print("*" * 20, "数据写入结束", "*" * 20) dv = t.DataVisualization(excel=".\\data\\filmData.xls") + print(dv.Scatter2()) + print(dv.treeMap()) + print(dv.Scatter1()) print(dv.wordCloud()) - diff --git a/tools.py b/tools.py index f9a5079..58510b7 100644 --- a/tools.py +++ b/tools.py @@ -8,7 +8,7 @@ from xlutils.copy import copy import time -from pyecharts.charts import Bar, WordCloud +from pyecharts.charts import WordCloud from pyecharts import options as opts from pyecharts.charts import TreeMap from pyecharts.globals import SymbolType @@ -27,16 +27,32 @@ class DataResolve: def __init__(self, html): self.html = html + try: + xlrd.open_workbook(".\\data\\filmData.xls") + open(".\\data\\logs.txt") + except: + # 初始化本地存储excel表格 + print("filmData.xls文件不存在,创建filmData.xls文件") + workbook = xlwt.Workbook() # 创建工作簿对象 + workbook.add_sheet("sheet1") # 创建工作表对象 + workbook.save(".\\data\\filmData.xls") + print("创建logs.txt日志文件") + open(".\\data\\logs.txt", 'w') # 初始化日志文件 + ''' 提供外部访问方法 ''' def resolve(self): - data = self.__resolvePicture() + log = open(".\\data\\logs.txt", 'a', encoding='utf-8') + currentTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + log.write('\n' + str(currentTime) + "爬取数据!") + log.close() + picture = self.__resolvePicture() score = self.__resolveScore() film = self.__resolveEvaluations() # self.__resolveFilmDownLoad() - return '' + return '解析结束' ''' 解析图片 @@ -201,7 +217,7 @@ def writeExcelAppend(self, path): sheets_name = workbook.sheet_names() sheet = workbook.sheet_by_name(sheets_name[0]) rows = sheet.nrows - new_workbook = copy(workbook) + new_workbook = copy(workbook) # xlrd对象转为xlwt对象 new_sheet = new_workbook.get_sheet(0) dataStyle = xlwt.XFStyle() # 创建数据样式对象 dataAlign = xlwt.Alignment() @@ -231,11 +247,13 @@ def writeExcelAppend(self, path): class Utils: - workbook = xlrd.open_workbook(".\\data\\filmData.xls") - sheet = workbook.sheets()[0] names = [] comments = [] - rows = int(sheet.nrows) + + def __init__(self, excel_path): + workbook = xlrd.open_workbook(excel_path) + self.sheet = workbook.sheets()[0] + self.rows = int(self.sheet.nrows) def chooseData(self): # 随机从excel表中选出4个名称 @@ -245,6 +263,43 @@ def chooseData(self): self.comments.append(self.sheet.cell_value(flag, 4)) return self.names, self.comments + @staticmethod + def choosePage(page_number=1): + start = 0 # 实际起始位置 + if page_number == 1: # 第一页 + start = 0 + return start + elif page_number == 2: # 第二页 + start = 25 + return start + elif page_number == 3: # 第三页 + start = 50 + return start + elif page_number == 4: # 第四页 + start = 75 + return start + elif page_number == 5: # 第五页 + start = 100 + return start + elif page_number == 6: # 第六页 + start = 125 + return start + elif page_number == 7: # 第七页 + start = 150 + return start + elif page_number == 8: # 第八页 + start = 175 + return start + elif page_number == 9: # 第九页 + start = 200 + return start + elif page_number == 10: # 第十页 + start = 225 + return start + else: + raise '页码不合法' + + ''' 生成可视化文件 @@ -266,7 +321,7 @@ def treeMap(self): workbook = xlrd.open_workbook(self.path) sheet = workbook.sheets()[0] rows = sheet.nrows - flag = 0 + flag = 0 # excel表有效数据标识符 firstPage = [] secondPage = [] thirdPage = [] @@ -391,15 +446,15 @@ def Scatter1(self): ) .render(".\\data\\scatter1.html") ) + return '散点图1生成成功' ''' 散点图2 ''' def Scatter2(self): - u = Utils - data = u.chooseData(u) - print(data) + u = Utils(excel_path='.\\data\\filmData.xls') + data = u.chooseData() c = ( Scatter() .add_xaxis(u.names) @@ -410,6 +465,4 @@ def Scatter2(self): ) .render(".\\data\\scatter2.html") ) - - - + return '散点图2生成成功' From d31314c571ec33ac48d96a0985fd86c8e7ccb62c Mon Sep 17 00:00:00 2001 From: snowball <851317190@qq.com> Date: Fri, 17 Dec 2021 11:45:11 +0800 Subject: [PATCH 2/2] =?UTF-8?q?tools.py=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/misc.xml | 2 +- .idea/spider.iml | 2 +- __pycache__/request.cpython-39.pyc | Bin 1010 -> 1772 bytes __pycache__/tools.cpython-39.pyc | Bin 1854 -> 12163 bytes data/filmData.xls | Bin 23552 -> 0 bytes ...4\350\231\253\346\227\266\351\227\264.txt" | 1 - main.py | 9 ++++++--- tools.py | 19 ++++++++++++------ 8 files changed, 21 insertions(+), 12 deletions(-) delete mode 100644 data/filmData.xls delete mode 100644 "data/\350\256\260\345\275\225\347\210\254\350\231\253\346\227\266\351\227\264.txt" diff --git a/.idea/misc.xml b/.idea/misc.xml index d1e22ec..6b7f31a 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/.idea/spider.iml b/.idea/spider.iml index 0e4e9fa..102589c 100644 --- a/.idea/spider.iml +++ b/.idea/spider.iml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/__pycache__/request.cpython-39.pyc b/__pycache__/request.cpython-39.pyc index 099c621f9637d97a463a4ea809f203de1e0a4971..db6f30c02f8fafe4d6034ee2bb1a119ff8443f96 100644 GIT binary patch literal 1772 zcma)6&2QX96rZujYwuT@eu%UnkdHNLmwc2ov_M;>rAVbw)wEQyA}nWTlJ&;B-p-7Z zbmf%_DU}dJLP8vhfF^3A!Ud>=s8GwDzrk0?lAO46fj8bXEQkYRy*KmT%>3S)ncuTt zE*B8AtA`%@w@rk8QAU5$!8i>fPJp6_;t;vL9=kZRHCNAi;*zX4T;n{V8r5$hs;_8n zj^b(LkZstHrm9N!Hw}!_Ai@U4kiv8|iUBi208B!STgWwN4p7Y0yv(l0Ovn^fRccS0 z0RttIAmS1zim4Xhj-Ftu4KJuo>dnj$DXY5 zsKH>#1VB{AUYR&v85te5r~Nsf2fI7%ws}fOpUc;_Ux0%;nrq6S!J=5EW{vrjanUwn zId^no`)8Ps4}seH_EGoYdz<$kZhgOTL>c#PcJFTd{^Z>^t~gez3&~T9_byhX`aF}V z#hTTK2F-c52*G45JTO^mw0O{zDUoa$bWJuw$4H4_;asZ6JWNT;pJy-udGIm>{u=Rp z(ETwsd1B_OfYfG0Gg_MU!*J%(jcU#3jY~YLv#NxNRsgxr?4(g?-QaoHSppFUKp~y{ zNys1`#5r8R7A7F=;tm@skaAT~>1k7>CLkFf4q^lhsN)3Hfm*A$qsfe3R9n$8Fk_9Z zqmC|(wHzhu@b+pJ_>s*@bInTdI_{8!tmR>y0jww_1~m>Lnggs{lB*XxCN(=&hHCAg zn$%d(_z#IzFC~CL^Q#&l|04!1?8HFzGA+^)pyj2WX(U9oW4G_Lf&wR{wAB zU~g}Rv$t=&uW!7APZ98XV9LSSQ?(Dg_#Z7+&$sp9UiZt7yB|E*TK{PC$<56NAI^Vv zN3|bMakyLL;ItrWj7hKQH(0DLfAi7CuRndhwf@yed=Sj;r{8r~zuCNfXY>7yejG>R z>T%P&@E4ia@?|Xx*uVU@$Dee+xZB=enW4V)XXb*iaTW%ZJI+B68;3NNnLBY z>PyM^D3mT|?4sY=b&WU$J^d5s;2;2Rg$VGl6eL)UkMLrYNoXNwF^({j7C#VF15TYwCAM- z&uc_94jGI~o_8H?KvBT+diSm>m_M(SqEVkxNpV%M7Kq5HfkrfIPv&z>uH31{;gw_* lg@O-(&7W0Du_;^Chn9h7=d@n!rSrO?rBFn);Dp(y{{`k4+ARP8 delta 535 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 E2Osn5qyPW_ literal 1854 zcmbtU&5ImG6tAl8p6U5?HLKCEhs_G=L^38K2(oH0t0IJD$q>|br0MPIo%GmWQ&qD| zhMv>pAcE+@yE8ZUCjJ59$)kTjUB!?53!d^`&(6|W1{AEO-s@NO>b+mp`&D_ZR-Him z?AM>XUo1j?N2A;fFm6GYT@ajb8WCrysYAhL5sMASpyWfs4Q@Up+?+ATfe)rkbRk?Cx>1X^$#BS_dO9Gh;$hE3MR6U2coaiG?Lxyfwo;Y zOhVATX*H)Q}9?d{67bYOLHzf^w-8rh7L31QI-<8ua40euJL@nNm)tOhM7VVB&d2xiO=ZC^m<} zD>gJ2Y-%VgC&LQ2W^8Ka=CH~uSg(-s+ShE4eE!nZQg&|5C}=jXXJ^ttj&w6m02_ds;jy;-$dgi=p$cNCkL4*P44Z(NklkP`o31+=d(o1v0$&Y*mr39o;#^t#Vikw#Y_FXw?b*4y)}xH5 zR9}3o1wMJg0D+c796&A8uG*U*&0?lwiB0s{0^t~k@{Q$P!bR(%X?u6M)pw9<5}#O` I*|cdq2K5BPvH$=8 diff --git a/data/filmData.xls b/data/filmData.xls deleted file mode 100644 index e918787c705339915132703967e5e0281f2d2290..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23552 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