1. # -*- coding = ut-8 -*-
    2. # @Time : 2021/5/20 下午 13:14
    3. # @Author : PHC
    4. # @File demo1.py
    5. # @Software : PyCharm
    6. # 每查看一个详情信息 需要消耗100积分
    7. #若要在其他的工程文件中,需要在File->setting->python Interpreter 中重新下载导入的模块包
    8. import requests
    9. import urllib
    10. import json
    11. import xlwt
    12. import time
    13. #打印爬取到网页的全部信息 全局变量
    14. dataListOne=[] #按页数,数组长度为所查的页数。
    15. def allUrl(current):
    16. # pageNum(current)
    17. baseurl = 'https://t.cjcyw.com/cjcy/ship/list?_index={}'.format(current) #地址拼接。当前访问的指定页数
    18. # print(current) #输出的结果为1
    19. #不同的设备head 中的信息不一致,后续需要更改。
    20. head = {
    21. "Cookie": "cjcy_session_id=a7ff8f24-fcb2-43d3-80e4-53a7d466cea9; yunsuo_session_verify=6a7ff9e97531e25af61b0eeef6212804",
    22. # 'Accept': 'application/json',
    23. 'User-Agent': 'cicy/5.4(iPhone; iOS 12.0; Scale/3.00)',
    24. # 'Accept-Language':"zh-Hans-CN;q=1,da-DK;q=0.9",
    25. # "Content-Length": 62,
    26. "Content-Type": "application/x-www-form-urlencoded",
    27. "Connection": "keep-alive",
    28. "Host": "t.cjcyw.com"
    29. }
    30. request = urllib.request.Request(baseurl, headers=head)
    31. response = urllib.request.urlopen(request)
    32. page = response.read().decode("utf-8") #输出为str
    33. # print(page)
    34. contents=json.loads(page) #转为python对象。
    35. # print(contents,'contents的结果是什么11111111111')
    36. content=contents['data']['records'] #每一页中的所有数据
    37. # print(content,'content的结果是什么222222222') #[ {1},{2},{3}.... ]
    38. # print(type(content),'content的类型是什么') #输出结果是 <class 'list'>
    39. datalist = []
    40. for i in content: #遍历每一页中的每一条数据,一页共20条数据。
    41. # print(i)
    42. data=[] #将每条船的信息加入到data列表中
    43. # print(i,'i的结果是什么') #将所需页面数的records中的数据提取。
    44. startLocation=i['suozaidi'] #打印每一条信息中需要提取的信息------1所在地
    45. # print(startLocation)
    46. data.append(startLocation)
    47. endLocation=i['daodadi'] # 2到达地
    48. data.append(endLocation)
    49. shipName=i['title']
    50. data.append(shipName) # 3船名
    51. dunwei=i['dunwei'] # 4吨位
    52. # print(dunwei)
    53. data.append(dunwei)
    54. # datalist.append(data)
    55. # print(data)
    56. #将每一个船的信息,形成一个列表。
    57. #每一条船第一次普通信息的加载
    58. aidFirst = i['aid'] # 下一个详情所需的参数接口 所有接口的参数均为 aid
    59. contentsOne=oneShipMessage(aidFirst) #打印所查看的一只船的信息。
    60. # print(type(contentOne),'contentOne 的类型是什么') #输出结果是: <class 'dict'> 是列表类型。
    61. # print(contentsOne,'contentOne的结果') # 打印单个船舶第一次加载的信息
    62. aid=contentsOne['aid'] #下一次请求时,所需的参数。 应该与上一个aid相等。便于验证
    63. # data.append(aid)
    64. oneShipLocation=contentsOne['suozaidi'] # 验证第二次加载得信息,所在地与第一次是否相同
    65. # print(oneShipLocation)
    66. # data.append(oneShipLocation)
    67. starDate=contentsOne['kaishiriqi'] # 5 提取到的开始日期还未转换,当前显示的形式是从1970,01 到所爬取出的时间的秒数。
    68. currentDate=time.strftime("%Y-%m-%d",time.localtime(starDate)) #经过标准格式化输出的时间
    69. data.append(currentDate)
    70. #每一条船第二次查看 所加载的会员信息
    71. contentTwo=twoVipAll(aidFirst)
    72. beizhu=contentTwo['beizhu11']
    73. data.append(beizhu) # 6 备注的信息
    74. LinkName=contentTwo['publishLinkMan']
    75. data.append(LinkName) #7 联系人名字
    76. linkPhone=contentTwo['publishTel']
    77. data.append(linkPhone) #8 联系人电话
    78. # datalistOne datalist
    79. datalist.append(data) # 注:[ [ [data],[data],[data] ] , [ [data],[data],[data] ] , .. ]
    80. print("第",current,"页,第",len(datalist),"条",data) #查看每打印一条船舶信息的进度
    81. dataListOne.append(datalist) #将第一次加载出来的信息,加入列表中
    82. # print(dataListOne)
    83. return dataListOne
    84. #需要打印的页面条数数据
    85. # def pageNum(number):
    86. # for current in range(1,number): # 由于range()中是左闭右开,且allUrl(current)当中的current数值只能从一开始。故当pagenNum(4) 传过来的参数为4 时,只能打印3条。
    87. # allUrl(current)
    88. #第一次点击查看 查看一个船的普通信息
    89. def oneShipMessage(aid):
    90. url="https://t.cjcyw.com/cjcy/ship/detail?aid={}".format(aid)
    91. head = {
    92. "Cookie": "cjcy_session_id=a7ff8f24-fcb2-43d3-80e4-53a7d466cea9; yunsuo_session_verify=6a7ff9e97531e25af61b0eeef6212804",
    93. # 'Accept': 'application/json',
    94. 'User-Agent': 'cicy/5.4(iPhone; iOS 12.0; Scale/3.00)',
    95. # 'Accept-Language':"zh-Hans-CN;q=1,da-DK;q=0.9",
    96. # "Content-Length": 62,
    97. "Content-Type": "application/x-www-form-urlencoded",
    98. "Connection": "keep-alive",
    99. "Host": "t.cjcyw.com"
    100. }
    101. request = urllib.request.Request(url, headers=head)
    102. response = urllib.request.urlopen(request)
    103. pageOne= response.read().decode("utf-8")
    104. # print(type(pageOne),"pageOne的类型是什么") #输出结果 <class 'str'>
    105. contents=json.loads(pageOne)
    106. # print(contents,'contents的结果333333333') # 输出结果正确
    107. content=contents['data']
    108. # print(content,'content 的结果444444444') # { }
    109. # print(type(content)) #输出结果为 <class 'dict'> 已经转成dict列表形式,应该转成list。
    110. return content # 返回第一次加载后的信息
    111. # 第二次查看中间过度段的请求过程。需要积分,会员形式查看
    112. def twoVipCenter(aid): #需要传过来一个参数,名为aid
    113. #中间有一个过度请求的地址信息
    114. #过度请求
    115. url="https://t.cjcyw.com/cjcy/user/viewDetail?aid={}".format(aid)
    116. head={
    117. "Cookie": "cjcy_session_id=a7ff8f24-fcb2-43d3-80e4-53a7d466cea9",
    118. "Host": "t.cjcyw.com",
    119. "User-Agent": "cicy/5.4 (iPhone; iOS 12.0; Scale/3.00)",
    120. "Content-Type": "application/x-www-form-urlencoded"
    121. }
    122. request=urllib.request.Request(url,headers=head)
    123. response=urllib.request.urlopen(request)
    124. pagetwo=response.read().decode("utf-8")
    125. contents=json.loads(pagetwo)
    126. # print(contents) # 成功
    127. return contents
    128. #第二次所需要查看的详情信息。
    129. def twoVipAll(aid):
    130. #中间过渡段返回过来的内容:
    131. contentVipCenter=twoVipCenter(aid)
    132. message=contentVipCenter['message'] # 'message':'成功'--------输出结果成功,能够正常度过中间访问过程。 **********(意味这一段没毛病)
    133. # print(message)
    134. url="https://t.cjcyw.com/cjcy/ship/detail?aid={}".format(aid)
    135. head={
    136. "Cookie": "cjcy_session_id=a7ff8f24-fcb2-43d3-80e4-53a7d466cea9",
    137. "Host": "t.cjcyw.com",
    138. "User-Agent": "cicy/5.4 (iPhone; iOS 12.0; Scale/3.00)",
    139. "Content-Type": "application/x-www-form-urlencoded"
    140. }
    141. request=urllib.request.Request(url,headers=head)
    142. response=urllib.request.urlopen(request)
    143. pagetwoAll=response.read().decode("utf-8")
    144. contents=json.loads(pagetwoAll)
    145. content=contents['data']
    146. # print(content,'第二次查看时的contents的内容')
    147. return content
    148. #保存所有的信息到Excel表格中。
    149. def saveMessagePath(number):
    150. for current in range(1,number): #左闭右开 [a,b)
    151. # print(current) #输出结果是 1 2
    152. datalist= allUrl(current)
    153. # print(datalist)
    154. timePass=time.localtime() #输出系统的当前时间,当前时间为格林尼治时间? 秒数,
    155. timeNow=time.strftime("%Y-%m-%d",timePass) #将系统的当前时间格式化输出,一天打印一次,若重复打印,最好将已输出的文件名字更改一下,避免数据丢失,重名会覆盖。
    156. savePath="%s长江船运网数据信息.xls"%(timeNow) #保存的文件命名格式:当前时间(年-月-日)+文件名
    157. table=xlwt.Workbook(encoding="utf-8",style_compression=0)
    158. sheet=table.add_sheet("长江船运网数据信息",cell_overwrite_ok=True)
    159. col=("所在地","到达地","船名","吨位","开始日期","备注信息","船主名字","电话") #定义列名
    160. # print(datalist)
    161. #定义表格中的列名
    162. for i in range(0,len(col)):
    163. sheet.write(0,i,col[i]) #向表格中写入列名
    164. for pages in range(len(datalist)): #遍历每一页。总页数是datalist元组的长度
    165. pagesData=datalist[pages] #取出每一页中的20条数据。
    166. # print("看看有多少页====",pages) # 当输入的number页数为3时,打印两条数据。datalist长度为2。pages输出结果0,1
    167. # print("看看第%s页有多少条船舶数据"%(pages+1)) #页数在列表中,下标从0开始计算 或(pages+1)
    168. if pages < number:
    169. for j in range(0,20): #遍历每一页中的20条数据
    170. print("第%s条"%(j+1)) #该条程序已执行
    171. item =pagesData[j] #取出每一条数据
    172. # print(item) #输出结果是想要的形式。
    173. for a in range(0,len(col)):
    174. sheet.write(j+pages*20+1,a,item[a]) #Excel中表格第一行,第一列坐标为(0,0) sheet.write(行,列,写入的数据)
    175. table.save(savePath)
    176. if __name__=='__main__':
    177. # pageNum(3) #页数更改处,从2开始
    178. pagesNum=5 #定义所需要查找的页数。
    179. print("当前需要查询的页数共有", pagesNum-1, "页,每页应当有20条,请耐心等待查询的结果\n结果加速查询中......")
    180. saveMessagePath(pagesNum) #输入口,定义所需要查看的页数。。20条信息为一页。
    181. # twoVipCenter(6614081) #测试第二次查看中间过渡段能否成功访问。
    182. # twoVipAll(6614081) #测试第二次查看所有信息时,能否访问成功