Python项目——《爱豆行程早知道》
项目概况
在学习Python一学期后,追星少女为追星做了一个小项目——爬取爱豆网上的偶像行程。功能选择上主要功能:1、查询指定月份行程 2、查询下一行程 3、订阅行程消息(行程更新发送邮件提醒用户)。
查询行程功能
查询行程功能有一点局限性,更适用于在Python IDE上运行,行程可以直接打印在控制台上。
运行效果如图:
查询当月行程
查询11月行程
订阅行程功能
前面几个功能只能算是对爬取数据的一个显示,接下来才是本系统的重头戏——“订阅”。订阅可选择订阅下一行程或是订阅全月行程。
订阅下一行程
首先设置用户收到邮件的时间n天(建议0-7天),在距离行程n天时向指定的收件人发送下一行程提醒,并附上偶像图片。
订阅下一行程的运行结果,如下图:
订阅全月行程
依然,首先设置用户收到邮件的时间n天(建议0-7天),在距离每月1号n天时向指定的收件人发送全月行程安排的excel文件,同样附上偶像图片。
订阅全月行程的运行结果,如下图:
机场行程分析之地理坐标系线图
代码实现
展示完整个项目的功能,接下来就讲讲我是如何用代码实现这些功能的。
我选题时很幸运,想要爬取的网页没有设置反爬,周围好多同学在获取网页内容上就被反爬挡住了脚步。我直接使用requests 库通过网络连接获取网页内容,beautifulsoup4库对获得的网页内容进行处理。
使用第三方库时如果没有安装过首先应该安装:
采用pip指令进行安装,以下使用的其他第三方库默认安装完毕,没有安装的麻烦自己百度一下,在此我就不赘述了。
pip install requests
pip install beautifulsoup4
爬取网页信息
首先将获取网页内容封装起来,如下:
def getHtmlText(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
r.encoding = "utf-8"
return r.text
except:
return "获取网页内容有异常"
根据用户输入的idol名称进入idol消息动态页面(大概是以前做项目JSON解析写多了,查找想要的信息时我总是喜欢一层一层去找,其实很多时候直接可以找最底层的标签,当然这也是beautifulsoup4的一个劣势,之后我用了lxml,直接可以根据xpath查找到想要的节点,这个库也非常推荐。不过用lxml查找后返回的是一个list对象,所以处理的时候要写成img[0]。):
def getIdolPage(starName):
global idolName, imgSrc
starUrl = "http://idol001.com/star/" + starName + ".html"
starHtml = getHtmlText(starUrl)
starSoup = BeautifulSoup(starHtml, "html.parser") # 指定的偶像页面
card_head = starSoup.find("div", {"class": "card-head"})
wholeTripUrl = card_head.find("a", {"class": "textLink-red card-head-more"}).attrs.get("href") # 全部行程页面的url
#XPath查找
selector = lxml.html.fromstring(starHtml)
img = selector.xpath("//*[@id='repContent']/div[2]/img")
imgSrc = img[0].get("src") #图片地址
name = selector.xpath("//*[@id='repContent']/div[2]/div/span")
idolName = name[0].text
#print(idolName)
return wholeTripUrl
获取网页内容的代码都像getIdolPage(starName)一样,我就不放每一块的代码了,大家可以直接在下面看整个项目的完整代码。
发送邮件
python发邮件学习地址
python发邮件需要掌握两个模块的用法,smtplib和email,这俩模块是python自带的,只需import即可使用。smtplib模块主要负责发送邮件,email模块主要负责构造邮件。
使用smtplib发送邮件:
开始我借鉴上面提到的学习博客使用SMTP()来发送邮件,可能是调试的时候发的太频繁了,被服务器发现了,百度后发现第一种方式发的是普通信息,就换成了SMTP_SSL(),发送安全邮件,问题解决。
方式一
smtp = smtplib.SMTP()
smtp.connect("smtp.126.com", "25")
方式二
smtp = smtplib.SMTP_SSL("smtp.126.com", 465)
smtp.helo()
smtp.ehlo()
时间判断
def sendMailDate(tripTime,oday):
tripDate = datetime.strptime(tripTime, "%Y-%m-%d %H:%M")#行程时间转化为datetime类型
sendDate = tripDate - timedelta(days=oday)#行程发送时间
return sendDate
datetime.timedelta对象代表两个时间之间的时间差,两个date或datetime对象相减就可以返回一个timedelta对象。 在这里我可以判断发送订阅邮件的时间。