需求:爬取电影名,评分,主演
捉妖记2 梁朝伟 白百何 9.3分
喵星人 古天乐 马丽 9.0分
祖宗十九代 岳云鹏 吴京 8.9分
奇门遁甲 大鹏 倪妮 9.0分
勇敢者游戏:决战丛林 道恩・强森 凯文・哈特 9.3分
首先对网页链接分析,第一页:https://dianying.2345.com/list/——-.html,第二页:https://dianying.2345.com/list/——-2.html。组成为https://dianying.2345.com/list/ +——-+页号.html。
再分析爬取内容:
分析网页格式可以看出要爬取的内容都在’v_picConBox mt15’这个div中
电影名
这里要注意一个爬取小坑的问题。2345电影网在每页电影大全中,穿插了广告(坑B网)。所以要特别注意下,不能去爬广告,因为电影和广告的html是不一样的。
接下来则是代码部分
“””
Created on Fri Apr 13 19:08:03 2018
@author: oyzm
“”“
import urllib.request
import urllib.error
from urllib.parse import quote
from bs4 import BeautifulSoup
import pybloom_live
import string
import codecs
import time
import random
from mylog import MyLog
boom=pybloom_live.BloomFilter( capacity=10000,error_rate=0.0001 )
class DyItem(object):
title=None
action=None
score=None
class GetDianYing(object):
def init(self):
#https://dianying.2345.com/list/——-1.html
self.urlBase=’https://dianying.2345.com/list/’
self.mylog=MyLog()
self.pages=self.getPages(self.urlBase)
self.context=self.spider(self.urlBase,self.pages)
self.piplines(self.context)
#发请求
def getHttp(self,url):
try:
#time.sleep(random.randint(0,5))
url=quote(url,string.printable)
response=urllib.request.urlopen(url)
except error.URLError as e:
self.mylog.debug('爬取%s失败,原因%s'%url,e)
else:
self.mylog.debug('爬取%s成功'%url)
return response.read()
#取页数
def getPages(self,urlBase):
httpRe=self.getHttp(urlBase)
soup=BeautifulSoup(httpRe,'lxml')
liTag=soup.find("div",attrs={"class":"v_page"})
tags=liTag.find_all("a")
lastTag=tags[-2]
total=int( lastTag.get_text().strip() )
#由于没做代理,只爬5页测试使用
return 5
#爬取
def spider(self,urlBase,pages):
url=''
context=[]
for i in range(pages):
url=urlBase+'-------'+str(i)+'.html'
self.mylog.debug('开始爬取%s'%url)
httpRe=self.getHttp(url)
soup=BeautifulSoup(httpRe,'lxml')
divTag=soup.find("div",attrs={"class":"v_picConBox mt15"})
ulTag=divTag.find("ul",attrs={"class":"v_picTxt pic180_240 clearfix"})
liTag=ulTag.find_all("li")
for tag in liTag:
dyItem=DyItem()
#避免广告
if tag.get("media")!=None:
dyItem.score=tag.find("span",attrs={"class":"pRightBottom"}).find("em").get_text()
dyItem.title=tag.find("em",attrs={"class":"emTit"}).find("a").get_text()
Faction=tag.find("span",attrs={"class":"sDes"})
Saction=Faction.find_all("em")
#action: a b
actions=''
for action in Saction:
action=action.find("a").get_text().strip()
actions=actions+action+' '
dyItem.action=actions
context.append(dyItem)
self.mylog.debug("爬取电影为<<%s>>信息成功"%dyItem.title)
return context
#存储
def piplines(self,context):
dyName='2345电影.txt'
nowTime=time.strftime('%Y-%m-%d %H:%M:%S\r\n',time.localtime())
with codecs.open(dyName,'w','utf8') as fp:
fp.write('run time:%s'%nowTime)
for item in context:
fp.write('%s \t %s \t %s \t \r\n'
%(item.title,item.action,item.score) )
self.mylog.info(u'将电影名为<<%s>>的数据存入%s'%(item.title,dyName))
if name==’main‘:
GetDianYing()
日志代码 (mylog )
-- coding: utf-8 --
“””
Created on Fri Apr 6 20:49:35 2018
@author: oyzm
“”“
import logging
import getpass
import sys
class MyLog(object):
def init(self):
self.user=getpass.getuser()
#定义日志构造器
self.logger=logging.getLogger(self.user)
#设置级别
self.logger.setLevel( logging.DEBUG )
#取出日志名
self.logName=sys.argv[0][0:-3]+'.log'
#定义日志格式
self.formatter=logging.Formatter( ' %(asctime)-12s %(filename)s %(funcName)s %(name)s %(message)s\n' )
#定义处理器
self.fileHandle=logging.FileHandler( self.logName,encoding='utf-8' )
self.fileHandle.setFormatter( self.formatter )
self.fileHandle.setLevel(logging.ERROR)
self.streamHandle=logging.StreamHandler()
self.streamHandle.setFormatter( self.formatter )
self.streamHandle.setLevel(logging.DEBUG)
#添加处理器
self.logger.addHandler(self.fileHandle)
self.logger.addHandler(self.streamHandle)
#按级别输出
def debug( self,msg ):
self.logger.debug(msg)
def error( self,msg ):
self.logger.error(msg)
def warn( self,msg ):
self.logger.warn(msg)
def info( self,msg ):
self.logger.info(msg)
def critical( self,msg ):
self.logger.critical(msg)
if name==’main‘:
ml=MyLog()
ml.debug(‘这是一个error测试’)
ml.warn(‘这是一个error测试’)
ml.error(‘这是一个error测试’)