欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

python編寫網(wǎng)頁爬蟲腳本并實現(xiàn)APScheduler調(diào)度

系統(tǒng) 1730 0

前段時間自學(xué)了python,作為新手就想著自己寫個東西能練習(xí)一下,了解到python編寫爬蟲腳本非常方便,且最近又學(xué)習(xí)了MongoDB相關(guān)的知識,萬事具備只欠東風(fēng)。

程序的需求是這樣的,爬蟲爬的頁面是京東的電子書網(wǎng)站頁面,每天會更新一些免費的電子書,爬蟲會把每天更新的免費的書名以第一時間通過郵件發(fā)給我,通知我去下載。

一、編寫思路:

  1.爬蟲腳本獲取當(dāng)日免費書籍信息

  2.把獲取到的書籍信息與數(shù)據(jù)庫中的已有信息作比較,如果書籍存在不做任何操作,書籍不存在,執(zhí)行插入數(shù)據(jù)庫的操作,把數(shù)據(jù)的信息存入MongoDB

  3.執(zhí)行數(shù)據(jù)庫插入操作時,把更新的數(shù)據(jù)以郵件的形式發(fā)送出來

  4.用APScheduler調(diào)度框架完成python腳本調(diào)度

二、腳本的主要知識點:

1.python簡單爬蟲

本次用到的模塊有urllib2用來抓取頁面,導(dǎo)入模塊如下:

            
import urllib2
from sgmllib import SGMLParser
          

urlopen()方法獲取網(wǎng)頁HTML源碼,都存儲在content中,listhref()類主要的功能是解析HTML代碼,處理HTML類型的半結(jié)構(gòu)化文檔。

            
content = urllib2.urlopen('http://sale.jd.com/act/yufbrhZtjx6JTV.html').read()
listhref = ListHref()
listhref.feed(content)
          

listhref()類代碼可以在下面全部代碼中查詢到,這里只說幾個關(guān)鍵點:

listhref()類繼承了SGMLParser 類并重寫了其中的內(nèi)部方法。SGMLParser 將HTML分解成有用的片段,比如開始標(biāo)記和結(jié)束標(biāo)記。一旦成功地分解出某個數(shù)據(jù)為一個有用的片段,它會根據(jù)所發(fā)現(xiàn)的數(shù)據(jù),調(diào)用一個自身內(nèi)部的方法。為了使用這個分析器,您需要子類化 SGMLParser類,并且重寫父類的這些方法。

SGMLParser 將 HTML 分析成不同類數(shù)據(jù)及標(biāo)記,然后對每一類調(diào)用單獨的方法:
開始標(biāo)記 (Start_tag)
是一個開始一個塊的 HTML 標(biāo)記,像 ,, ,

           等,或是一個獨一的標(biāo)記,象 
          
等。本例當(dāng)它找到一個開始標(biāo)記 ,SGMLParser將查找名為 start_a或do_a的方法。如果找到了,SGMLParser會使用這個標(biāo)記的屬性列表來調(diào)用這個方法;否則,它用這個標(biāo)記的名字和屬性列表來調(diào)用unknown_starttag方法。
結(jié)束標(biāo)記 (End_tag)
是結(jié)束一個塊的HTML標(biāo)記,像 ,, 或
等。本例中當(dāng)找到一個結(jié)束標(biāo)記時,SGMLParser 將查找名為end_a的方法。如果找到,SGMLParser調(diào)用這個方法,否則它使用標(biāo)記的名字來調(diào)用unknown_endtag。
文本數(shù)據(jù)(Text data)
獲取文本塊,當(dāng)不滿足其它各類別的任何標(biāo)記時,調(diào)用handle_data獲取文本。

以下的幾類在本文中沒有用到
字符引用 (Character reference)
用字符的十進制或等同的十六進制來表示的轉(zhuǎn)義字符,當(dāng)找到該字符,SGMLParser用字符調(diào)用 handle_charref 。
實體引用 (Entity reference)
HTML實體,像&ref,當(dāng)找到該實體,SGMLParser實體的名字調(diào)用handle_entityref。
注釋 (Comment)
HTML注釋, 包括在 之間。當(dāng)找到,SGMLParser用注釋內(nèi)容調(diào)用handle_comment。
處理指令 (Processing instruction)
HTML處理指令,包括在 之間。當(dāng)找到,SGMLParser用指令內(nèi)容調(diào) handle_pi。
聲明 (Declaration)
HTML聲明,如DOCTYPE,包括在 之間。當(dāng)找到,SGMLParser用聲明內(nèi)容調(diào)用handle_decl。

具體的說明參考API:http://docs.python.org/2/library/sgmllib.html?highlight=sgmlparser#sgmllib.SGMLParser

2.python操作MongoDB數(shù)據(jù)庫

首先要安裝python對mongoDB的驅(qū)動PyMongo,下載地址:https://pypi.python.org/pypi/pymongo/2.5

導(dǎo)入模塊

            
import pymongo
          

連接數(shù)據(jù)庫服務(wù)器127.0.0.1和切換到所用數(shù)據(jù)庫mydatabase

            
mongoCon=pymongo.Connection(host="127.0.0.1",port=27017)
db= mongoCon.mydatabase
          

查找數(shù)據(jù)庫相關(guān)書籍信息,book為查找的collection

            
bookInfo = db.book.find_one({"href":bookItem.href})
          

為數(shù)據(jù)庫插入書籍信息,python支持中文,但是對于中文的編碼和解碼還是比較復(fù)雜,相關(guān)解碼和編碼請參考http://blog.csdn.net/mayflowers/article/details/1568852

            
b={
"bookname":bookItem.bookname.decode('gbk').encode('utf8'),
"href":bookItem.href,
"date":bookItem.date
}
db.book.insert(b,safe=True)
          

關(guān)于PyMongo請參考API文檔http://api.mongodb.org/python/2.0.1/

3.python發(fā)送郵件

導(dǎo)入郵件模塊

            
# Import smtplib for the actual sending function
import smtplib
from email.mime.text import MIMEText
          

"localhost"為郵件服務(wù)器地址

msg = MIMEText(context) #文本郵件的內(nèi)容
msg['Subject'] = sub #主題
msg['From'] = "my@vmail.cn" #發(fā)信人
msg['To'] = COMMASPACE.join(mailto_list) #收信人列表

            
def send_mail(mailto_list, sub, context): 
COMMASPACE = ','
mail_host = "localhost"
me = "my@vmail.cn"
# Create a text/plain message
msg = MIMEText(context) 
msg['Subject'] = sub 
msg['From'] = "my@vmail.cn"
msg['To'] = COMMASPACE.join(mailto_list)

send_smtp = smtplib.SMTP(mail_host) 

send_smtp.sendmail(me, mailto_list, msg.as_string()) 
send_smtp.close()
          

應(yīng)用文檔:http://docs.python.org/2/library/email.html?highlight=smtplib#

4.Python調(diào)度框架ApScheduler

下載地址https://pypi.python.org/pypi/APScheduler/2.1.0

官方文檔:http://pythonhosted.org/APScheduler/#faq

API:http://pythonhosted.org/APScheduler/genindex.html

安裝方法:下載之后解壓縮,然后執(zhí)行python setup.py install,導(dǎo)入模塊

            
from apscheduler.scheduler import Scheduler
          

ApScheduler配置比較簡單,本例中只用到了add_interval_job方法,在每間隔一段時間后執(zhí)行任務(wù)腳本,本例中的間隔是30分鐘??蓞⒖紝嵗恼耯ttp://flykite.blog.51cto.com/4721239/832036

            
# Start the scheduler 
sched = Scheduler()
sched.daemonic = False 
sched.add_interval_job(job,minutes=30) 
sched.start()
          

關(guān)于daemonic參數(shù):

apscheduler會創(chuàng)建一個線程,這個線程默認(rèn)是daemon=True,也就是默認(rèn)的是線程守護的。

在上面的代碼里面,要是不加上sched.daemonic=False的話,這個腳本就不會按時間運行。

因為腳本要是沒有sched.daemonic=False,它會創(chuàng)建一個守護線程。這個過程中,會創(chuàng)建scheduler的實例。但是由于腳本運行速度很快,主線程mainthread會馬上結(jié)束,而此時定時任務(wù)的線程還沒來得及執(zhí)行,就跟隨主線程結(jié)束而結(jié)束了。(守護線程和主線程之間的關(guān)系決定的)。要讓腳本運行正常,必須設(shè)置該腳本為非守護線程。sched.daemonic=False

附:全部腳本代碼

All Code

            
#-*- coding: UTF-8 -*-
import urllib2
from sgmllib import SGMLParser
import pymongo
import time
# Import smtplib for the actual sending function
import smtplib
from email.mime.text import MIMEText
from apscheduler.scheduler import Scheduler

#get freebook hrefs
class ListHref(SGMLParser):
def __init__(self):
SGMLParser.__init__(self)
self.is_a = ""
self.name = []
self.freehref=""
self.hrefs=[]

def start_a(self, attrs):
self.is_a = 1
href = [v for k, v in attrs if k == "href"]
self.freehref=href[0]

def end_a(self):
self.is_a = ""

def handle_data(self, text):
if self.is_a == 1 and text.decode('utf8').encode('gbk')=="限時免費":
self.hrefs.append(self.freehref)
#get freebook Info
class FreeBook(SGMLParser):
def __init__(self):
SGMLParser.__init__(self)
self.is_title=""
self.name = ""
def start_title(self, attrs):
self.is_title = 1
def end_title(self):
self.is_title = ""
def handle_data(self, text):
if self.is_title == 1: 
self.name=text
#Mongo Store Module
class freeBookMod:
def __init__(self, date, bookname ,href):
self.date=date
self.bookname=bookname
self.href=href

def get_book(bookList):
content = urllib2.urlopen('http://sale.jd.com/act/yufbrhZtjx6JTV.html').read()
listhref = ListHref()
listhref.feed(content)

for href in listhref.hrefs:
content = urllib2.urlopen(str(href)).read()
listbook=FreeBook()
listbook.feed(content)
name = listbook.name
n= name.index('》')
#print (name[0:n+2])
freebook=freeBookMod(time.strftime('%Y-%m-%d',time.localtime(time.time())),name[0:n+2],href)
bookList.append(freebook)
return bookList

def record_book(bookList,context,isSendMail):
# DataBase Operation
mongoCon=pymongo.Connection(host="127.0.0.1",port=27017)
db= mongoCon.mydatabase
for bookItem in bookList:
bookInfo = db.book.find_one({"href":bookItem.href})

if not bookInfo:
b={
"bookname":bookItem.bookname.decode('gbk').encode('utf8'),
"href":bookItem.href,
"date":bookItem.date
}
db.book.insert(b,safe=True)
isSendMail=True
context=context+bookItem.bookname.decode('gbk').encode('utf8')+','
return context,isSendMail 

#Send Message
def send_mail(mailto_list, sub, context): 
COMMASPACE = ','
mail_host = "localhost"
me = "my@vmail.cn"
# Create a text/plain message
msg = MIMEText(context) 
msg['Subject'] = sub 
msg['From'] = "my@vmail.cn"
msg['To'] = COMMASPACE.join(mailto_list)

send_smtp = smtplib.SMTP(mail_host) 

send_smtp.sendmail(me, mailto_list, msg.as_string()) 
send_smtp.close() 

#Main job for scheduler 
def job(): 
bookList=[]
isSendMail=False; 
context="Today free books are"
mailto_list=["mailto@mail.cn"]
bookList=get_book(bookList)
context,isSendMail=record_book(bookList,context,isSendMail)
if isSendMail==True: 
send_mail(mailto_list,"Free Book is Update",context)

if __name__=="__main__": 
# Start the scheduler 
sched = Scheduler()
sched.daemonic = False 
sched.add_interval_job(job,minutes=30) 
sched.start()
          


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。。?/p>

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 91免费国产在线 | www.色综合 | 国产免费福利网站 | 色播视频在线播放 | 国产精品久久久久久久久久大牛 | 日韩黄色网 | 九九99九九视频在线观看 | 91水蜜桃 | 久久99国产精品成人欧美 | 午夜精品在线播放 | av黄色在线 | 奇米影视亚洲四色8888 | 国产日韩一区二区三区 | 久久久久无码国产精品一区 | 国产亚洲精品久久久久久国 | 亚洲一区和二区 | 久久综合九色综合欧美9v777 | 99精品视频免费在线观看 | 午夜亚洲| 久久精品美女 | 国产a做爰全过程片 | 国产精品久久久久久久午夜 | 九九热在线精品视频 | 久久久人 | 26uuu.mobi| 亚洲国产91 | 色男人的天堂久久综合 | 精品国产精品久久 | 色婷婷久久久 | 水野朝阳128部合集在线 | 久www| 99这里只有精品66视频 | 天天草夜夜爽 | 欧美日韩一区二区三区在线观看 | 免费看的黄网站 | 久久青草精品免费资源站 | 日日碰日日操 | 日日夜夜天天久久 | 私房色播 | 911影院| 六月丁香婷婷天天在线 |