最近的原则就是把以前爬虫爬到一半出现各种bug,导致爬不下去的网站全部清理掉,第三只豆瓣爬虫来了,主要爬了豆瓣的热门影评内容,部分代码写的不是特别的简洁,现阶段主要是为了掌握各种方法,后期再进一步完善,希望有看到的小伙伴能够帮忙指正。
目标:
爬取豆瓣的热门影评(https://movie.douban.com/review/best/)主要爬取:影评标题、影片详情链接、影评人、影片名、评分、影评以及影评时间
遇到的困难:
爬取影评详情链接时用到的方法,层层获取到内容,其次是影评的内容要链接到影片详情的链接,也就是跳转到另一个页面去爬取,最重要的一点我还没有解决,在爬取部分影评的时候,遇到的需要登录才能访问,需要模拟登陆,这一点还没攻破,假期结束主要学习动态页面的爬虫和模拟登陆,小白成长中,加油!
代码:
import urllib
from urllib.request import urlopen
from bs4 import BeautifulSoup
import os
import csv
import re
import time
import urllib.error
#定义豆瓣影评爬虫类
class DBYP():
def __init__(self):
self.baseUrl=baseUrl
self.pageNum=0
#得到指定页面全部内容
def askUrl(self,url):
request=urllib.request.Request(url)
try:
response=urllib.request.urlopen(request)
html=response.read().decode('utf-8')
return html
except urllib.error.URLError as e:
if hasattr(e,'reason'):
print(u'连接影片详情页面失败,原因:',e.reason)
return None
#传入某一页索引,获取页面代码
def getPage(self,pageNum):
try:
url=baseUrl+str(pageNum)
request=urllib.request.Request(url)
response=urllib.request.urlopen(request)
html=response.read().decode('utf-8')
# print(html)
return html
except urllib.error.URLError as e:
if hasattr(e,'reason'):
print(u'连接豆瓣影评失败,原因:',e.reason)
return None
#使用BeautifulSoup方法爬取页面所要获取的内容
def getPageInfo(self,pageNum,html):
bs=BeautifulSoup(html,'lxml')
content_field=bs.select('header.main-hd')
# print(content_field)
item=[]
for each in content_field:
title=each.select('a.title-link')[0]
href = each.find_all('h3', {'class': "title"})[0].find_all('a')[0]#一层一层的获取到内容,最后href[href]提取出链接中的内容
url = href['href'] # 影片详情链接
# print(url)
author = each.select('a > span')[0]
subject_title = each.select('a.subject-title')[0]
rate = each.select('span.main-title-hide')[0]
pattern =self.askUrl(url) # 获取影片详情的html
html = BeautifulSoup(pattern, 'lxml') # 解析HTML文件
content = html.select('div.review-content')[0]
print(content.text)
# desc = re.sub(remove '', str(content)) # 去掉标签
date = each.select('span.main-meta')[0]
time.sleep(2)
item.append((title.text, url, author.text, subject_title.text, rate.text, content.text, date.text))
# print(item)
return item
#将文件保存为csv格式
def write_Data(self,contents):
csvFile=open('film_review.csv','a',newline='',encoding='utf-8')
writer=csv.writer(csvFile)
writer.writerow(('标题','影评详情链接','影评人','影片名','评分/5','影评','日期'))
for item in contents:
writer.writerow(item)
csvFile.close()
#删除已有文件
def deleteOldTxt(self):
filename='film_review.csv'
if os.path.exists(filename):
os.remove(filename)
print('发现旧名单,已删除')
#设置页数,存取数据
def start(self):
print('正在读取热门影评:')
IndexPage=self.getPage(0)
try:
for i in range(0,100,20):
print('正在读取第'+str(i)+'页的内容:')
page=self.getPage(i)
html=spider.getPage(i)
contents=self.getPageInfo(page,html)
print(contents)
self.write_Data(contents)
time.sleep(2)
except IOError as e:
print('写入异常,原因:'+ e.message)
finally:
print('写入任务完成')
baseUrl='https://movie.douban.com/review/best/?start='
spider=DBYP()
spider.deleteOldTxt()
spider.start()
贴出来的代码,现在用是没有问题的,但是涉及到有的网页需要登录才能爬取,所以后期对于模拟登陆这一part需要进一步完善