Python爬蟲爬取愛奇藝、騰訊視頻電影相關信息(改進版)---團隊第一階段沖刺


愛奇藝

 1 import time  2 import traceback  3 import requests  4 from lxml import etree  5 import re  6 from bs4 import BeautifulSoup  7 from lxml.html.diff import end_tag  8 import json  9 import pymysql  10 #連接數據庫 獲取游標
 11 def get_conn():  12     """
 13  :return: 連接,游標  14     """
 15     # 創建連接
 16     conn = pymysql.connect(host="82.157.112.34",  17                     user="root",  18                     password="root",  19                     db="MovieRankings",  20                     charset="utf8")  21     # 創建游標
 22     cursor = conn.cursor()  # 執行完畢返回的結果集默認以元組顯示
 23     if ((conn != None) & (cursor != None)):  24         print("數據庫連接成功!游標創建成功!")  25     else:  26         print("數據庫連接失敗!")  27     return conn, cursor  28 #關閉數據庫連接和游標
 29 def close_conn(conn, cursor):  30     if cursor:  31  cursor.close()  32     if conn:  33  conn.close()  34     return 1
 35 def get_iqy():  36     # 獲取數據庫總數據條數
 37     conn, cursor = get_conn()  38     sql = "select count(*) from movieiqy"
 39     cursor.execute(sql)     # 執行sql語句
 40     conn.commit()       # 提交事務
 41     all_num = cursor.fetchall()[0][0]       #cursor 返回值的類型是一個元祖的嵌套形式 比如( ( ) ,)
 42     pagenum=int(all_num/48)+1               #這里是計算一個下面循環的起始值 每48個電影分一組
 43     # print(pagenum)
 44     print("movieiqy數據庫有", all_num, "條數據!")  45 
 46 
 47     url = "https://pcw-api.iqiyi.com/search/recommend/list?channel_id=1&data_type=1&mode=11&page_id=1&ret_num=48&session=ee4d98ebb4e8e44c8d4b14fa90615fb7"
 48     headers = {  49         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
 50  }  51     # response=requests.get(url=url,headers=headers)
 52     # response.encoding="utf-8"
 53     # page_text=response.text
 54     # print(page_text)
 55     """
 56     """
 57     #  58     temp_list = []      #暫時存放單部電影的數據
 59     dataRes = []        #每次循環把單部電影數據放到這個list
 60     for i in range(1, 137):         #循環1-136 第137 json 是空的 也就是全部爬完
 61         url = "https://pcw-api.iqiyi.com/search/recommend/list?channel_id=1&data_type=1&mode=11&page_id=1&ret_num=48&session=ee4d98ebb4e8e44c8d4b14fa90615fb7"
 62         url_0 = "https://pcw-api.iqiyi.com/search/recommend/list?channel_id=1&data_type=1&mode=11&page_id="
 63         url_0 = url_0 + str(i) + "&ret_num=48&session=ad1d98bb953b7e5852ff097c088d66f2"
 64         print(url_0)        #輸出拼接好的url
 65         response = requests.get(url=url_0, headers=headers)  66         response.encoding = "utf-8"
 67         try:  68             page_text = response.text  69             #解析json對象
 70             json_obj = json.loads(page_text)  71             #這里的異常捕獲是因為 測試循環的次數有可能超過電影網站提供的電影數 為了防止后續爬到空的json對象報錯
 72             json_list = json_obj['data']['list']  73         except:  74             print("捕獲異常!")  75             return dataRes          #json為空 程序結束
 76         for j in json_list:         # 開始循環遍歷json串
 77             # print(json_list)
 78             name = j['name']        #找到電影名
 79             print(name)  80  temp_list.append(name)  81             #異常捕獲,防止出現電影沒有評分的現象
 82             try:  83                 score = j['score']      #找到電影評分
 84                 print(score)  85  temp_list.append(score)  86             except KeyError:  87                 print( "評分---KeyError")  88                 temp_list.append("iqy暫無評分")            #替換字符串
 89 
 90             link = j['playUrl']             #找到電影鏈接
 91  temp_list.append(link)  92             # 解析播放狀態
 93             """
 94  獨播:https://www.iqiyipic.com/common/fix/site-v4/video-mark/only.png  95  VIP:https://pic0.iqiyipic.com/common/20171106/ac/1b/vip_100000_v_601_0_21.png  96  星鑽:https://www.iqiyipic.com/common/fix/site-v4/video-mark/star-movie.png  97             """
 98             state = []  99             pay_text = j['payMarkUrl']         #因為播放狀態只有在一個圖片鏈接里有 所以需要使用re解析出類似vip和only(獨播)的字樣
100             print(pay_text) 101             if (len(pay_text) == 0):            #如果沒有這個圖片鏈接 說明電影是免費播放
102                 state="免費"
103             else: 104                 find_state = re.compile("(.*?).png") 105                 state = re.findall(find_state, pay_text)        #正則匹配鏈接找到vip
106                 # print(state[0])
107 
108                 if(len(state)!=0):              #只有當鏈接不為空再執行
109                     # print(state)
110                     # 再次解析
111                     part_state=str(state[0]) 112                     part_state=part_state.split('/') 113                     print(part_state[-1]) 114                     state = part_state[-1][0:3]      #字符串分片
115                     # 這里只輸出了三個字符,如果是獨播,頁面顯示的是only,我們設置為”獨播“
116                     if (state == "onl"): 117                         state = "獨播"
118                     if (state == "sta"): 119                         state = "星鑽"
120                     if(state == "vip"): 121                         state="VIP"
122             print(state) 123             # 添加播放狀態
124             # print(state)
125  temp_list.append(state) 126  dataRes.append(temp_list) 127             # print(temp_list)
128             temp_list = [] 129 
130         print('___________________________') 131     return dataRes 132 
133 def insert_iqy(): 134     cursor = None 135     conn = None 136     try: 137         count=0 138         list = get_iqy() 139         print(f"{time.asctime()}開始插入愛奇藝電影數據") 140         conn, cursor = get_conn() 141         sql = "insert into movieiqy (id,name,score,path,state) values(%s,%s,%s,%s,%s)"
142         for item in list: 143             print(item) 144             count = count + 1
145             if (count % 48 == 0): 146                 print('___________________________') 147             #異常捕獲,防止數據庫主鍵沖突
148             try: 149                 cursor.execute(sql, [0, item[0], item[1], item[2], item[3] ]) 150             except pymysql.err.IntegrityError: 151                 print("重復!跳過!") 152 
153         conn.commit()  # 提交事務 update delete insert操作
154         print(f"{time.asctime()}插入愛奇藝電影數據完畢") 155     except: 156  traceback.print_exc() 157     finally: 158  close_conn(conn, cursor) 159     return; 160 
161 if __name__ == '__main__': 162     # get_iqy()
163     insert_iqy()

騰訊視頻

 1 import requests  2 import json  3 from bs4 import BeautifulSoup       #網頁解析獲取數據
 4 import sys  5 import re  6 import urllib.request,urllib.error #制定url,獲取網頁數據
 7 import sqlite3  8 import xlwt     #excel操作
 9 import time  10 import pymysql  11 import traceback  12 #連接數據庫 獲取游標
 13 def get_conn():  14     """
 15  :return: 連接,游標  16     """
 17     # 創建連接
 18     conn = pymysql.connect(host="82.157.112.34",  19                     user="root",  20                     password="root",  21                     db="MovieRankings",  22                     charset="utf8")  23     # 創建游標
 24     cursor = conn.cursor()  # 執行完畢返回的結果集默認以元組顯示
 25     if ((conn != None) & (cursor != None)):  26         print("數據庫連接成功!游標創建成功!")  27     else:  28         print("數據庫連接失敗!")  29     return conn, cursor  30 #關閉數據庫連接和游標
 31 def close_conn(conn, cursor):  32     if cursor:  33  cursor.close()  34     if conn:  35  conn.close()  36     return 1
 37 
 38 #爬取騰訊視頻電影數據
 39 def get_ten():  40     conn,cursor=get_conn()  41     sql="select count(*) from movieten"
 42  cursor.execute(sql)  43  conn.commit()  44     all_num=cursor.fetchall()[0][0]  45 
 46     print("movieten數據庫有",all_num,"條數據!")  47     # https://v.qq.com/channel/movie?listpage=1&channel=movie&sort=18&_all=1&offset=0&pagesize=30
 48     url="https://v.qq.com/channel/movie?listpage=1&channel=movie&sort=18&_all=1"        #鏈接
 49     param={                                                                             #參數字典
 50         'offset':0,  51         'pagesize':30
 52  }  53     headers={                                                                            #UA偽裝
 54         'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '+
 55                        'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36'
 56  }  57     # param['offset']=all_num
 58     offset = 0                                                                           #拼接url
 59     dataRes = []  60     findLink = re.compile(r'href="(.*?)"')  # 鏈接
 61     findName = re.compile(r'title="(.*?)"')  # 影片名
 62     findScore= re.compile(r'<div class="figure_score">(.*?) </div>')        #評分
 63     #3*170
 64     for i in range(0,300):  65         # res = urllib.request.urlopen(url) #urllib不推薦使用
 66         res = requests.get(url=url,params=param,headers=headers)       #編輯request請求
 67         # print(url)
 68         res.encoding='utf-8'                                           #設置返回數據的編碼格式為utf-8
 69         html=BeautifulSoup(res.text,"html.parser")      #BeautifulSoup解析
 70         part_html = html.find_all(r"a", class_="figure")               #找到整個html界面里a標簽對應的html代碼,返回值是一個list
 71         # print(part_html)
 72         if (len(part_html) == 0):  73             print("頁面返回空!")  74             return dataRes  75         offset = offset + 30                                            #修改參數字典+30部電影
 76         print("下面從第"+str(offset)+"部電影開始:")  77         param['offset'] = offset  78         print(param['offset'])  79         for i in part_html:                                            #遍歷每一個part_html
 80             # print(i)
 81             words = str(i)  82             name=re.findall(findName, words)# 添加影片名
 83             score=re.findall(findScore, words)# 添加評分
 84             link=re.findall(findLink, words)# 添加鏈接
 85             findState=BeautifulSoup(words,'lxml')       #單獨解析播放狀態
 86             state=findState.select('a > img')           #找到img父級標簽
 87             if(len(state)==1):                          #免費電影不存在播放狀態的標志,所以當img長度是1的時候,需要補上一個空串
 88                 state.append("")  89             state_text=str(state[1])                    #拿到第二個img對應的內容,使用正則匹配到alt屬性對應的字符串
 90             # print(state_text)
 91             temp_state=re.findall('<img alt="(.*?)"', state_text)  92             if(len(temp_state)==0):  93                 temp_state.insert(0,"免費") # 添加播放狀態---免費
 94             # print(temp_state[0])
 95             list_=[]  96             if(len(score)==0):  97                 score.insert(0,"暫無評分")  98             for i in dataRes:  99                 if name[0] in i[0]: 100                     name.insert(0,name[0]+"(其他版本)") 101  list_.append(name[0]) 102  list_.append(score[0]) 103  list_.append(link[0]) 104  list_.append(temp_state[0]) 105             # list_.append(statu)
106             # print(list_)
107             print(list_) 108  dataRes.append(list_) 109     # print(dataRes) #打印最終結果
110     # list=html.select(".figure_score")
111     # for item in list:
112     # print(item)
113 
114     #把同一部電影的信息放到一個 [ ] 里面
115 
116     return dataRes 117 #插入到騰訊電影數據庫
118 def insert_ten(): 119     """
120  插入騰訊電影數據 121  :return: 122     """
123     cursor = None 124     conn = None 125     try: 126         list = get_ten() 127         print(f"{time.asctime()}開始插入騰訊電影數據") 128         conn, cursor = get_conn() 129         sql = "insert into movieten (id,name,score,path,state) values(%s,%s,%s,%s,%s)"
130         for item in list: 131             try: 132                 cursor.execute(sql,[0,item[0],item[1],item[2],item[3]]) 133             except pymysql.err.IntegrityError: 134                 print("重復!跳過!") 135         conn.commit()  # 提交事務 update delete insert操作
136         print(f"{time.asctime()}插入騰訊電影數據完畢") 137     except: 138  traceback.print_exc() 139     finally: 140  close_conn(conn, cursor) 141     return ; 142 if __name__ == '__main__': 143     # conn,cursor=get_conn()
144     # list=[]
145     # res_list=get_ten()
146     # print(res_list)
147     insert_ten()

 數據獲取方式:微信搜索關注【靠譜楊閱讀人生】回復【電影】。
整理不易,資源付費,謝謝支持。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM