版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
題目概述實(shí)驗(yàn)題目:實(shí)驗(yàn)七網(wǎng)絡(luò)爬蟲。實(shí)驗(yàn)要求與目的:熟悉爬蟲工作原理,用相關(guān)的python工具包實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲。實(shí)驗(yàn)內(nèi)容:爬取TOP250電影的所有短評(píng)以及電影的相關(guān)數(shù)據(jù)。爬取TOP250豆瓣電影所有短評(píng),以及電影的相關(guān)信息,包括電影類型,上映時(shí)間,以及演員列表等信息。開發(fā)平臺(tái)及開源工具本次信息檢索實(shí)驗(yàn)使用的是python語言,開發(fā)工具為PyCharm2021.3,操作系統(tǒng)為Windows10和Ubuntu18.04服務(wù)器,第三方庫均使用pip安裝。本次實(shí)驗(yàn)使用的第三方庫主要有selenium(自動(dòng)登錄與信息爬取)、matplotlib(詞頻統(tǒng)計(jì)可視化)、numpy(矩陣處理)、jieba(分詞)等。詳細(xì)設(shè)計(jì)文件說明douban_movies.py主要就是構(gòu)造TOP250排行榜每一頁的鏈接,然后解析每一頁的電影名和電影頁鏈接,然后發(fā)出爬取電影頁信息的Request,之后利用xpath或者pyquery正常解析網(wǎng)頁信息即可。defstart_requests(self):
base_url='/top250?start=$&filter='
forstartinrange(10):
url=str.replace(base_url,'$',str(start*25))
(url)
yieldRequest(url,callback=self.parse_top250)
defparse_top250(self,response):
top250_movie_info_item=TOP250MovieInfoItem()
html=response.text
doc=pq(html)
all_movies=doc('#content>div>div.article>ol>li>div>')
formovieinall_movies.items():
sleep_time=random.uniform(0.5,1)
time.sleep(sleep_time)
movie_link=movie('div.hd>a').attr('href')
title=movie('div.hd>a>span.title').text()
top250_movie_info_item['title']=title
top250_movie_info_item['movie_link']=movie_link
(top250_movie_info_item)
yieldtop250_movie_info_item
#然后發(fā)出爬取每個(gè)movie的具體信息的request
(movie_link)
yieldRequest(movie_link,callback=self.parse_movie_item)pipeline.py#因?yàn)樵趐rocess_item中會(huì)根據(jù)不同的Item進(jìn)行不同的查詢防止爬取重復(fù)的信息,所以對(duì)不同的collection設(shè)置了不同的索引,畢竟最后爬取到的短評(píng)有33萬多條,設(shè)置一下索引對(duì)速度還是有提升的
defopen_spider(self,spider):
self.client=pymongo.MongoClient(self.mongo_uri)
self.db=self.client[self.mongo_db]
self.db[TOP250MovieInfoItem.collection].create_index([('movie_link',pymongo.ASCENDING)])
self.db[MovieInfoItem.collection].create_index([('movie_link',pymongo.ASCENDING)])
self.db[CommentInfoItem.collection].create_index([('commenter_link',pymongo.ASCENDING),('comment_page_link',pymongo.ASCENDING)])
self.db[CommenterInfoItem.collection].create_index([('commenter_link',pymongo.ASCENDING)])
#process_item主要是根據(jù)不同的Item進(jìn)行查詢是否重復(fù)和插入
defprocess_item(self,item,spider):
ifisinstance(item,TOP250MovieInfoItem):
condition={'movie_link':item.get('movie_link')}
elifisinstance(item,MovieInfoItem):
condition={'comments_link':item.get('comments_link')}
elifisinstance(item,CommentInfoItem):
condition={'commenter_link':item.get('commenter_link'),
'comment_page_link':item.get('comment_page_link')}
elifisinstance(item,CommenterInfoItem):
condition={'commenter_link':item.get('commenter_link')}
result=self.db[item.collection].find_one(condition)
ifresultisNone:
self.db[item.collection].insert(dict(item))
returnitemmiddleware.pymiddleware中只使用了SeleniumMiddleware,其中大部分代碼是破解模擬登錄時(shí)破解滑動(dòng)驗(yàn)證碼,由于代碼比較多,破解滑動(dòng)驗(yàn)證碼的具體代碼請(qǐng)自行查看。defprocess_request(self,request,spider):
('PhantomJSisStarting')
try:
self.browser.get(request.url)
time.sleep(1)
html=self.browser.page_source
current_url=request.url
try:
need_login=self.browser.find_element_by_xpath('//*[@id="db-global-nav"]/div/div[1]/a')
('需要登錄')
login_link=need_login.get_attribute('href')
self.open(login_link)
ifself.password_error():
('用戶名或密碼錯(cuò)誤')
#如果不需要驗(yàn)證碼直接登錄成功
ifself.login_successfully():
('不需要驗(yàn)證碼直接登錄成功')
#登陸成功以后跳回原來的頁面
self.browser.get(current_url)
else:
#需要驗(yàn)證碼的情況下登錄
self.login_with_auth()
ifself.login_successfully():
('需要驗(yàn)證碼的情況下登錄成功')
#登陸成功以后跳回原來的頁面
self.browser.get(current_url)
elifself.password_error():
('需要驗(yàn)證碼的情況下登錄,用戶名或密碼錯(cuò)誤')
else:
('需要驗(yàn)證碼的情況下登錄,登錄失敗')
exceptNoSuchElementException:
('現(xiàn)在不需要登錄,所以找不到登錄元素')
#需要讓瀏覽器模擬隨機(jī)滑動(dòng)頁面,模擬人的行為
random_scroll_nums=random.randint(0,1)
foriinrange(random_scroll_nums):
random_scroll_distance1=random.randint(200,5000)
js='varq=document.documentElement.scrollTop='+str(random_scroll_distance1)
self.browser.execute_script(js)
time.sleep(0.3)
random_scroll_distance2=random.randint(200,5000)
js='varq=document.documentElement.scrollTop='+str(random_scroll_distance2)
self.browser.execute_script(js)
time.sleep(0.3)
random_sleep=random.uniform(0.2,0.8)
time.sleep(random_sleep)
returnHtmlResponse(url=request.url,body=html,request=request,encoding='utf-8',
status=200)
exceptTimeoutException:
self.logger.error('self.browser.get(request.url)happenedTimeoutException')
returnHtmlResponse(url=request.url,status=500,request=request)
exceptException:
self.logger.error('self.browser.get(request.url)happenederror')
returnHtmlResponse(url=request.url,status=500,request=request)comments.py短評(píng)的爬取過程和電影信息爬取略有不同,因?yàn)樵谂廊《淘u(píng)大約40分鐘之后就會(huì)無法爬取,查看日志文件發(fā)現(xiàn)報(bào)錯(cuò)全是Retry,估計(jì)是被檢測(cè)到異常暫時(shí)不允許訪問,所以寫一個(gè)shell腳本,每隔40分鐘啟動(dòng)一次爬蟲,因?yàn)槊看闻老x都是爬取幾部電影的短評(píng),所以在一個(gè)txt文件中寫一個(gè)接下來要爬取的電影index,一開始是0,每次爬蟲都會(huì)+10,所以經(jīng)過25次就能結(jié)束爬蟲,具體爬取的思路和電影信息的爬蟲差不多。defstart_requests(self):
#每次都要讀取這次要開始爬的電影的鏈接index
withopen('/home/zhiyong/data/next_link_num.txt','rt')asf:
#withopen('E:\PycharmProjects\some_data/next_link_num.txt','rt')asf:
next_link_index=f.read()
next_link_index=int(next_link_index)
#將后面開始讀的電影索引+10寫入文件
withopen('/home/zhiyong/data/next_link_num.txt','wt')asf:
#withopen('E:\PycharmProjects\some_data/next_link_num.txt','wt')asf:
new_next_link_index=next_link_index+10
f.write(str(new_next_link_index))
#后面可以加一個(gè)從數(shù)據(jù)庫中讀取已爬取的comment鏈接去重
movie_link_list=self.get_movie_link_list()
comment_page_link_list=self.get_comment_page_link_list()
forindexinrange(next_link_index,new_next_link_index):
ifindex>=250:
break
movie_link=movie_link_list[index]
time.sleep(3)
#分別爬取好評(píng),中評(píng),差評(píng)
choices=['h','m','l']
forchoiceinchoices:
#爬取每種評(píng)論之前先sleep一段時(shí)間
every_type_comments_sleep=random.randint(2,5)
time.sleep(every_type_comments_sleep)
comment_suffix='comments?start=$&limit=20&sort=new_score&status=P'
real_comments_link=movie_link+comment_suffix
ifchoice=='h':
real_comments_link=real_comments_link+'&percent_type=h'
elifchoice=='l':
real_comments_link=real_comments_link+'&percent_type=l'
else:
real_comments_link=real_comments_link+'&percent_type=m'
forstartinrange(25):
tmp_link=real_comments_link
request_comments_link=str.replace(tmp_link,'$',str(start*20))
ifrequest_comments_linknotincomment_page_link_list:
#然后可以爬取每個(gè)movie的短評(píng)信息
(request_comments_link)
yieldRequest(url=request_comments_link,callback=self.parse_comments)
else:
(request_comments_link)
('該鏈接已經(jīng)爬取過')commenters.py現(xiàn)階段爬取評(píng)論者的問題主要是速度太慢,畢竟一個(gè)網(wǎng)頁最多只有一個(gè)用戶的信息,再就是爬取時(shí)間過長也容易遇到Retry的問題,打算后面考慮一下有沒有什么彌補(bǔ)措施。defstart_requests(self):
commenter_link_list=self.get_commenter_link_list()
crawled_commenter_link_list=self.get_crawled_commenter_link_list()
forcommenter_linkincommenter_link_list:
ifcommenter_linknotincrawled_commenter_link_list:
crawled_commenter_link_list.append(commenter_link)
time.sleep(4)
(commenter_link)
yieldRequest(url=commenter_link,callback=self.parse_commenters)評(píng)論者信息爬取過程和前面其他爬蟲最大的不同就是解析網(wǎng)頁時(shí)一些異常情況的處理,比如賬號(hào)已注銷,賬號(hào)已被永久停用等...其他地方和前面的爬蟲大同小異。defparse_commenters(self,response):
commenter_info_item=CommenterInfoItem()
commenter_link=response.xpath('//*[@id="db-usr-profile"]/div[2]/ul/li[1]/a/@href').extract()
try:
commenter_link=commenter_link[0]
exceptIndexError:
#已經(jīng)注銷賬號(hào)的用戶會(huì)出錯(cuò)
('該用戶已經(jīng)主動(dòng)注銷帳號(hào)')
return
commenter_info_item['commenter_link']=commenter_link
location=response.xpath('//*[@id="profile"]/div/div[2]/div[1]/div/a/text()').extract()
iflocationisNone:
lcoation='未知'
else:
try:
location=location[0]
exceptIndexError:
lcoation='未知'
commenter_info_item['location']=location
register_timestamp=response.xpath('//*[@id="profile"]/div/div[2]/div[1]/div/div/text()[2]').extract()
try:
register_timestamp=register_timestamp[0]
#截取xxxx-xx-xx日期
result=re.findall('(.*)加入',register_timestamp)
register_timestamp=result[0]
register_timestamp=register_timestamp[0:10]
exceptIndexError:
#因?yàn)橛械馁~號(hào)根據(jù)log查看后發(fā)現(xiàn)是被永久停用的,沒法獲取注冊(cè)時(shí)間
register_timestamp=datetime.date.today()
commenter_info_item['register_timestamp']=register_timestamp
account_name=response.xpath('//*[@id="profile"]/div/div[2]/div[1]/div/div/text()[1]').extract()
try:
account_name=account_name[0]
account_name=str.strip(account_name)
commenter_info_item['account_name']=account_name[0]
exceptIndexError:
#這種情況是依據(jù)用戶管理細(xì)則,帳號(hào)已被永久停用。
('該依據(jù)用戶管理細(xì)則,帳號(hào)已被永久停用')
return
following_num=response.xpath('//*[@id="friend"]/h2/span/a/text()').extract()
try:
following_num=following_num[0]
#截取成員xxx中的數(shù)字
commenter_info_item['following_num']=following_num[2:]
exceptIndexError:
#如果沒有關(guān)注的人的話沒有用戶關(guān)注多少人,但會(huì)有被0人關(guān)注
following_num=0
follower_num=response.xpath('//*[@id="content"]/div/div[2]/p[1]/a/text()').extract()
follower_num=follower_num
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 廣東理工學(xué)院《能源與動(dòng)力測(cè)試技術(shù)》2023-2024學(xué)年第一學(xué)期期末試卷
- 廣東理工職業(yè)學(xué)院《測(cè)量學(xué)實(shí)驗(yàn)》2023-2024學(xué)年第一學(xué)期期末試卷
- 廣東江門幼兒師范高等專科學(xué)?!队耙暰巹 ?023-2024學(xué)年第一學(xué)期期末試卷
- 廣東工貿(mào)職業(yè)技術(shù)學(xué)院《遙感地學(xué)分析與應(yīng)用》2023-2024學(xué)年第一學(xué)期期末試卷
- 廣東工程職業(yè)技術(shù)學(xué)院《機(jī)器人學(xué)及其應(yīng)用》2023-2024學(xué)年第一學(xué)期期末試卷
- 廣東財(cái)貿(mào)職業(yè)學(xué)院《反應(yīng)工程概論》2023-2024學(xué)年第一學(xué)期期末試卷
- 新聞拍照培訓(xùn)課件
- 《風(fēng)險(xiǎn)統(tǒng)計(jì)分析》課件
- 廣安職業(yè)技術(shù)學(xué)院《跨屏傳播與營銷》2023-2024學(xué)年第一學(xué)期期末試卷
- 贛州職業(yè)技術(shù)學(xué)院《計(jì)算智能技術(shù)的實(shí)現(xiàn)》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025年1月八省聯(lián)考河南新高考物理試卷真題(含答案詳解)
- 物業(yè)管理服務(wù)人員配備及崗位職責(zé)
- 建設(shè)工程檢試驗(yàn)工作管理實(shí)施指引
- 鄭州2024年河南鄭州市惠濟(jì)區(qū)事業(yè)單位80人筆試歷年參考題庫頻考點(diǎn)試題附帶答案詳解
- 深靜脈血栓的手術(shù)預(yù)防
- 【9道期末】安徽省合肥市廬陽區(qū)2023-2024學(xué)年九年級(jí)上學(xué)期期末道德與法治試題
- 軟件租賃合同范例
- 腹腔鏡全胃切除手術(shù)配合
- 2024-2030年中國非物質(zhì)文化遺產(chǎn)市場(chǎng)前景調(diào)研及投資風(fēng)險(xiǎn)分析報(bào)告
- 匯川技術(shù)在線測(cè)評(píng)題及答案
- 酒店員工人事制度培訓(xùn)
評(píng)論
0/150
提交評(píng)論