使用selenium 多線程爬取愛奇藝電影信息
阿新 • • 發佈:2018-05-20
連接 獲取 ict 容易出錯 span column 分享圖片 odi attribute
使用selenium 多線程爬取愛奇藝電影信息
轉載請註明出處。
爬取目標:每個電影的評分、名稱、時長、主演、和類型
爬取思路:
源文件:(有註釋)
from selenium import webdriver
from threading import Thread
import threading
import time
import openpyxl #操作excel
#愛奇藝的看電影的url 不是首頁。
url=‘http://list.iqiyi.com/www/1/-8------------11-1-1-iqiyi--.html‘
#自定義一個線程類 實現多線程爬取
class M_Thread(Thread):
def __init__(self,name1,url):
Thread.__init__(self)
self.url=url
self.name1=name1
def run(self):
self.kind_movie=page(self.name1,self.url)
#page運行完後lock進行 讓 當前movie 結束
# 初始化爬蟲,從url中爬爬取各個種類相對於的連接。
def init():
# 瀏覽器 無界面 和有界面。
fireFoxOptions = webdriver.FirefoxOptions()
fireFoxOptions.set_headless()
Brower = webdriver.Firefox(firefox_options=fireFoxOptions)
# Brower = webdriver.Firefox()
Brower.get(url)
#定位到種類標簽 (發現不用Xpath容易出錯)
kind=Brower.find_element_by_xpath("/html/body/div[3]/div/div/div[1]/div[4]/ul")
#a標簽就是那個 連接
kinds=kind.find_elements_by_tag_name("a")
#將每個類型的頁面連接儲存到kinds_dict中
movie_kind_link={}
for a in kinds:
try:
if(a.text=="全部" or a.text==""): #去掉 全部類型 和一個空類型。
continue
movie_kind_link[a.text] = a.get_attribute("href")
except:
print("error!")
continue
Brower.close()
return movie_kind_link #返回的是 種類:url 字典。
def page(name,link):
#每一個種類 都打開一個excle儲存
wordbook=openpyxl.Workbook()
sheet1=wordbook.active
num=1
#初始化excle第一行
for qwe in ["電影名","時長","評分","類型","演員"]:
sheet1.cell(row=1,column=num,value=qwe)
num+=1
num=2
#本來一開始是用txt寫的但是布局太醜。 優點是速度快!
# 采用過 用數據庫存 ,但是同時寫入大量數據 總是會出莫名奇妙的錯誤。暫時沒解決
# file=open(name+".txt","w",encoding="utf-8")
fireFoxOptions = webdriver.FirefoxOptions()
fireFoxOptions.set_headless()
Br = webdriver.Firefox(firefox_options=fireFoxOptions)
# Br = webdriver.Firefox()
# try:
Br.get(link)
print("正在打開 %s 頁面"%name)
page = Br.find_element_by_class_name("mod-page")
page_href=[]
for aa in page.find_elements_by_tag_name("a"):
page_href.append(aa.get_attribute("href"))
for cc in page_href:
print("*****正在爬取 {} 的第 {} 頁*****".format(name,page_href.index(cc)+1))
# time.sleep(1)
# 第一頁不用重新打開
if(page_href.index(cc)!=0):
Br.get(cc)
#movie 即當前頁面的 電影tag 列表
movie=Br.find_element_by_class_name("wrapper-piclist").find_elements_by_tag_name("li")
for bb in movie:
# try:
things=bb.text.split("\n")
"""
這裏為什麽要區分?
愛奇藝很垃圾,有點電影評分不給,
但是在直接獲取text在if判斷和分元素去獲取四個屬性,我覺得還是if好用。
"""
if(len(things)==4):
sheet1.cell(row=num, column=1, value=things[2])
sheet1.cell(row=num, column=2, value=things[0])
sheet1.cell(row=num, column=3, value=things[1])
sheet1.cell(row=num, column=4, value=name)
sheet1.cell(row=num, column=5, value=things[3])
num+=1
elif (len(things) == 3):
sheet1.cell(row=num, column=1, value=things[1])
sheet1.cell(row=num, column=2, value="*")
sheet1.cell(row=num, column=3, value=things[0])
sheet1.cell(row=num, column=4, value=name)
sheet1.cell(row=num, column=5, value=things[2])
num +=1
else:
print("error (moive)")
# break
Lock_thread.release() # 解鎖
wordbook.save(name+".xlsx")
Br.close()
if __name__=="__main__":
#控制線程最大數量為3
Lock_thread= threading.Semaphore(3) #控制線程數為3
#kind:link
dict=init()
# print(dict)
#多線程爬取
for name1,link in dict.items():
Lock_thread.acquire() #枷鎖 ,在每一個page()運行完後解鎖
thread_live=M_Thread(name1,link)
print(name1," begin")
thread_live.start()
time.sleep(3)
使用selenium 多線程爬取愛奇藝電影信息