python写彩票抓取_Python|爬取彩票数据
pyhton|爬取彩票數(shù)據(jù)
背景:作者之前看到過不少朋友介紹利用python環(huán)境來爬取彩票數(shù)據(jù)的文章,方法大致都很類似,今天我也講一下關(guān)于傳統(tǒng)方法解析網(wǎng)頁獲得數(shù)據(jù),同時給大家介紹一種可能被大家忽略的方法,對于網(wǎng)頁結(jié)構(gòu)化的表的數(shù)據(jù)可以獲得比較高的數(shù)據(jù)獲取效率。
環(huán)境:Python3.7/MongoDB
簡要說明一下爬蟲的步驟:
1.選取目標網(wǎng)頁
2.觀察結(jié)構(gòu)(網(wǎng)頁結(jié)構(gòu)、數(shù)據(jù)結(jié)構(gòu))
3.選用解析工具(雖然有很多朋友喜歡使用Beautyfulsoup,但是在下還是建議使用xpath,因為效率比較高一點)
4.數(shù)據(jù)的持久化(俗話說光爬數(shù)據(jù)不儲存就是在耍流氓.需要考慮用什么方式儲存從頁面上獲取的信息,Excel、MySql還是MongoDB,本例將使用MongoDB做為儲存工具) 在正式開始工作之前我們來看看我們需要爬取的頁面是什么樣子 !
方法一:
方法一我們將直接通過常規(guī)方法對頁面進行解析獲取數(shù)據(jù)。下面我們通過翻頁來查看網(wǎng)頁地址都發(fā)生了些什么變化:
通過上面的觀察,我們可以發(fā)現(xiàn)在我們翻頁獲取新的網(wǎng)頁信息的時候,只有l(wèi)ist_x這個地方發(fā)生了變化,那么我們的工作就變得簡單了,我們只需要替換到list_x中x的值就可以獲取到新的一頁的數(shù)據(jù)了。那么我們的思路就是我們只需要解析一個網(wǎng)頁的數(shù)據(jù)并獲取,最后做個輪詢,那么我們就可以獲取整個網(wǎng)站的彩票數(shù)據(jù)了,想想就有點小激動。
那么接下來我們來看一看我們需要的數(shù)據(jù)都是放在什么樣的地方,我們怎么樣才能提取出來,現(xiàn)在觀察網(wǎng)頁結(jié)構(gòu),仔細一看也是相當?shù)暮唵巍N铱梢钥吹矫恳黄诘牟势毙畔⒍际欠旁谝粋€tr標簽對中,發(fā)現(xiàn)這個信息那么接下來代碼工作就可以開始了。
def pare(page):
url = http://kaijiang.zhcw.com/zhcw/html/3d/list_{}.html.format(page)
r = request.get(url,timeout=5)
selector = etree.HTML(r.text)
for td in selector.xpath('//tr')[2:-1]:
yield {'開獎日期': td.xpath('./td[position()=1]/text()')[0],
'期號': td.xpath('./td[position()=2]/text()')[0],
'百': td.xpath('./td[position()=3]/em/text()')[0],
'十': td.xpath('./td[position()=3]/em/text()')[1],
'個': td.xpath('./td[position()=3]/em/text()')[2],
'單選': td.xpath('./td[position()=4]/text()')[0],
'組3': td.xpath('./td[position()=5]/text()')[0],
'組': td.xpath('./td[position()=6]/text()')[0],
'銷售金額(元)': td.xpath('./td[position()=7]/strong/text()')[0]
}
簡單解釋一下上面的代碼,上面我們使用到的解析網(wǎng)頁的工具是xpath,先不說解析的效率,語法個人覺得比Beautyfulsoup好一些,當然這因人而異,也有不少人覺soup好用。既然我們之前分析得出我們需要的信息在tr的每個標簽中,我們先獲取到每個網(wǎng)頁中的所有tr標簽,做個輪詢我們就可以獲取到每個標簽對應(yīng)的信息了。
下面可以寫一個存數(shù)據(jù)庫的函數(shù)了:
def save_to_mongo(db_name, data, key_words):
''':db_name:數(shù)據(jù)表名稱:data:由parse傳入的可迭代的數(shù)據(jù):key_words:在存入數(shù)據(jù)庫時用到的關(guān)鍵字'''
for d in data:
key_word = {}
if isinstance(key_words, list):
key_word = {x: d[x] for x in key_words}
elif isinstance(key_words, str):
key_word = {key_words: d[key_words]}
[print(x) for x in data if data_base[db_name].update_one(key_word, {'$set': x}, True)]
萬事具備,先可以寫一個main函數(shù)了,直接把所有的數(shù)據(jù)存入mongodb數(shù)據(jù)庫了。
def main(num):
''':num:我們需要存入數(shù)據(jù)庫的最近num頁的數(shù)據(jù)'''
for n in range(1,int(num)+1):
p = parse(page=n)
save_to_mongo(db_name='自己取',data=p,key_words=['期號'])
打完收工,是不是相當簡單!!!
方法二:
這個是一個我感覺被大家忽略了的方法。遇到類似這樣的網(wǎng)頁表單,可能比上面方法仔細去分析網(wǎng)頁結(jié)構(gòu),查找數(shù)據(jù)在網(wǎng)頁中存放的位置和特點來的更簡單一點,那么這個方法就是什么呢? 千呼萬喚始出來,這個方法就是pandas中的read_html方法了,是不是很容易被大家忽略掉了,接下來就為大家介紹這種方法。import pandas as pd
def read(page):
''''''
url = http://kaijiang.zhcw.com/zhcw/html/3d/list_{}.html.format(page)
r = request.get(url,timeout=5)
df = pd.read_html(r.text)
keys = ['開獎日期','期號','中獎號碼','單選','組選3','組選6','銷售額(元)','返獎比例']
for d in df[0][2:-1].to_dict(orient='records'):
yield dict(zip(keys,[x for x in d.valus()][:-1]))
我們先來查看一下返回打印出來的結(jié)果:
這樣的結(jié)果就是我想要的結(jié)果了,其實代碼中df這部就可以獲取到一個dataframe數(shù)據(jù)表單,我把它轉(zhuǎn)換成了一個個的字典是為了往MongoDB數(shù)據(jù)庫存取方便,如果你沒有這樣需要,直接到pd.read_html(r.text)就可以了。重復(fù)上面的main函數(shù)就可以直接存數(shù)據(jù)庫,這樣的操作是不是比上面的解析網(wǎng)頁結(jié)構(gòu)要簡單了不少,以后遇到類似這樣的網(wǎng)頁表單結(jié)構(gòu),也可以采取類似的騷操作,就比大家熟悉的方法效率高一些。
總結(jié)
以上是生活随笔為你收集整理的python写彩票抓取_Python|爬取彩票数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 长安cs75plas2020款1.5T仪
- 下一篇: python为什么用两个等于号_刷Lee