python — 定时爬取猫眼电影排行榜

每次程序运行都是运行一次就结束了,那么能不能定时运行呢?接下来介绍python中的定时运行模块,schedule。

首先是模块的安装,推荐使用 pip 安装:

pip install schedule

接下来,在python的自带的IDLE中输入help('schedule'),就可以看到schedule的介绍。下面是schedule自带的例子:

import schedule
import time
    
def job(message='stuff'):
print("I'm working on:", message)
    
schedule.every(10).minutes.do(job)
schedule.every(5).to(10).days.do(job)
schedule.every().hour.do(job, message='things')
schedule.every().day.at("10:30").do(job)
    
while True:
    schedule.run_pending()
    time.sleep(1)

上面的例子,应该很容就看懂了。接下来可以开始实战了。

用python爬取猫眼电影TOP100榜

首先是自动发送邮件部分的实现。这方面的介绍可以在网上寻找相关的介绍,这里就不作过多的介绍,直接贴上使用的代码了

from email import encoders
from email.header import Header
from  email.mime.text import MIMEText
from email.utils import parseaddr, formataddr

#smtplib 负责发送邮件
import smtplib

class email_maoyan():
    def email_maoyan():
        #输入email地址和密码
        from_addr = '#####@qq.com' #在这里输入邮箱
        password ='password' #输入邮箱密码
        #输入收件人地址
        to_addr = '###@qq.com,####@qq.com' #输入收件人邮箱,可以输入多个地址,以都逗号隔开即可
        #输入SMTP服务器地址,smtp.qq.com
        smtp_server = 'smtp.qq.com' #input('SMTP server: ')
        #格式化邮件,如果name包含中文需要进行编码
        def _format_addr(s):
            name, addr= parseaddr(s)
        #Header对象将name进行utf-8解码获取Unicode,再encode()进行Unicode编码
            return formataddr((Header(name,'utf-8').encode(),addr))
        #构造MIMEText对象,第一个参数是邮件正文,第二个参数是MIME的subtype,'plain'表示纯文本
        #最后一定要用utf-8编码保证多语言兼容性
        msg = MIMEText('Have Done!','plain','utf-8')      #邮件的内容
        #把From、To和Subject添加到MIMEText中
        msg['From'] = _format_addr('猫眼电影爬虫<%s>' % from_addr)     #对中文进行编码
        msg['To'] = _format_addr('管理员 <%s>' % to_addr)               #对其中的中文进行编码
        msg['Subject'] = Header('爬取结果通知','utf-8').encode()  #邮件主题,显示在邮件的主题位置

        #SMTP协议默认端口是25
        server = smtplib.SMTP_SSL(smtp_server,465)

        #可以打印出和SMTP服务器交互的所有信息
        server.set_debuglevel(1)

        #login()方法用来登录SMTP服务器
        server.login(from_addr,password)

        #sendemail()方法是发送邮件,由于可以一次发给多个人,所以传入一个list

        #邮件正文是一个str,as_string()把MIMEText对象变成str
        #server.sendmail(from_addr,[to_addr],msg.as_string())
        server.sendmail(from_addr,to_addr.split(','),msg.as_string())      #发送给多个人
        server.quit()

邮件发送的部分就完成了,接下来完成爬取的部分

爬取的流程,包括网页分析,定制提取方法,存储信息。这些过程都比较简单,不做过多的介绍,同样直接贴上源码,同时将邮件,定时爬取功能都嵌入爬虫程序中。下面是源码:

#爬取猫眼电影排行榜,并利用邮件发送给自己

#导入需要的库
import requests
import csv
import json
from bs4 import BeautifulSoup
import schedule
from email_maoyan import email_maoyan
import time

#获取html页面
def get_html(url):
    #构造请求头
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36 QIHU 360SE'}
    try:
        r=requests.get(url, headers=headers)    #构造请求头,确保请求不会被拒绝
        r.raise_for_status
        #print(r.status_code)
        #r.encoding=r.apparent_encode()
        return r.text                #返回的将html转换text
    except:
        return "Error"





#页面解析
def html_parser(demo):
    lis=[]
    count=0
    soup=BeautifulSoup(demo,'lxml')    #这里使用lxml解析库
    #提取对应的信息,并将信息存储到字典中,同时将数据保存到text文本中
    for tags in soup.find_all(class_='movie-item-info'):              #寻找所有的tags标签
        for tag in tags:                                              #遍历标签,得到其中的一个
            #提取一部电影的信息
            try:
                for child in tag.children:                            #在一个标签下,获得其子节点
                    try:
                        lis.append(child.string.split(':')[-1].replace('\n','').strip())   #字符串预处理, 获得每一个子节点下的文本,并存入列表中
                        count+=1
                    #print(type(child.string))
                    except:
                        pass
            #将提取的信息存储到字典中,并存储到文本中,同时清空list和dic
            #print(lis)
            except:
                pass   
            if count==3:
                item={

                    'name':lis[0],
                    'actor':lis[1],
                    'time':lis[2]
                    }
                count=0
                #print(item)

                #保存数据
                save_result(item)
                #清空字典和列表,为下次做准备
                item.clear()
                lis.clear()          

#将爬到的结果存储到文件中
def save_result(item):

    #items=item
    #print(items)
    list_key=[]
    for key in item.keys():
            list_key.append(key)
    
    with open('C:/Users/LUXINWEN/Desktop/tet/maoyan.txt','a+',encoding='utf-8') as f:   
            #s=items[name]+items[star]+items[上映时间]
        s='{:<30}{:>40}{:>10}'.format(item[list_key[0]],item[list_key[1]],item[list_key[2]])
        f.write(s+'\n')
        #list_key.clear()  #清空列表
        #f.write('\n')
    
    #写入到csv文件中
    #解决每两行中间有空格的方法再打开文件的时候,写入参数 newline="" 即可
    with open("maoyan.csv",'a',newline="",encoding='utf-8') as csvfile:
        writer=csv.writer(csvfile)
        writer.writerow([item[list_key[0]], item[list_key[1]], item[list_key[2]]])
    """
    with open("maoyan.csv", 'a', newline='', encoding="utf-8") as csvfile:                   
        writer=csv.writer(csvfile)
        writer.writerow([item[list_key[0]], item[list_key[1]], item[list_key[2]]])
    """
   
    
    #写入到 json 格式数据中
    """
    with open('maoyan.json','a',encoding='utf-8') as jfile:
        #data=json.dumps(item)
        jfile.write(json.dumps(items, indent=2, ensure_ascii=False))
    """
    
    try:
        jsonfile=open('maoyan.json','a',encoding='utf-8')#data=json.dumps(item)   jsonfile.write(json.dumps(item, indent=2, ensure_ascii=False))                                                               
    except:
        print("error")
    else:
        #print(item)
        jsonfile.write(json.dumps(item, indent=2, ensure_ascii=False))
        jsonfile.close()
    
    list_key.clear()    #清空列表


#定义主函数
def main(offset):

    start_url="http://maoyan.com/board/4?offset="
    url=start_url+str(offset)
    demo=get_html(url)
   # print(demo)
    html_parser(demo)
   # print(items)
    #save_result(items)

def main_job():
    try:
        with open("maoyan.csv",'a',newline='',encoding='utf-8') as csvfile:
            writer=csv.writer(csvfile)
            writer.writerow(['name','actor','time'])                #写入头部信息
    except:
        print("error")

    for i in range(10):
        main(i*10)
    email_maoyan.email_maoyan()
    print("Done!")

#运行
if __name__ == '__main__':
    schedule.every(10).minutes.do(main_job)      #设置定时爬取的时间,这里为了可以得到快速验证,将时间设置的很短,可以根据需要自己设置
    print("It is working....")
    while True:
        schedule.run_pending()
        time.sleep(1)
    


猜你喜欢

转载自blog.csdn.net/qq_34246164/article/details/80844061