自動(dòng)讀取單位某系統(tǒng)數(shù)據(jù)

單位的環(huán)境監(jiān)控系統(tǒng)數(shù)據(jù)庫(kù)上移到省公司摊欠,省公司又不肯開(kāi)放權(quán)限去讀取數(shù)據(jù)。在同事的提醒下柱宦,使用爬蟲來(lái)抓取數(shù)據(jù)凄硼。為此我又得重新開(kāi)始學(xué)習(xí)新東西。這次的坑是python,基礎(chǔ)學(xué)習(xí)、建站税肪、抓蟲阅悍。折騰兩個(gè)月,終于在今天完成了對(duì)系統(tǒng)數(shù)據(jù)的讀取。

注:讀取的是公開(kāi)的數(shù)據(jù),不涉及保密內(nèi)容,目的是為了將人工轉(zhuǎn)為電腦自動(dòng)讀取

思路大概如下:

  • 通過(guò)瀏覽器的開(kāi)發(fā)者工具分析系統(tǒng)的請(qǐng)求數(shù)據(jù)尼斧,發(fā)現(xiàn)需要cookie,這個(gè)cookie登錄后才可用试吁。所以使用selenium來(lái)打開(kāi)網(wǎng)站棺棵,并使用帳號(hào)密碼自動(dòng)登錄。
  • 自動(dòng)登錄時(shí)需要驗(yàn)證碼熄捍,百度了一個(gè)比較簡(jiǎn)單的識(shí)別方法烛恤,成功率不高,但設(shè)置為自動(dòng)重復(fù)登錄余耽,可以掛著去喝茶缚柏,也不麻煩。使用的工具是tesseract碟贾,和pytesseract币喧、pillow。
  • 判斷是否登錄成功袱耽,若失敗則再次登錄杀餐,成功則構(gòu)造、發(fā)送請(qǐng)求包朱巨、獲取數(shù)據(jù)史翘。

說(shuō)明:

  • 所需軟件如下:
  1. tesseract識(shí)別軟件:需要在系統(tǒng)中安裝,方法很簡(jiǎn)單,就下載安裝恶座。
  2. 使用selenium時(shí),需下載webdriver沥阳,地址:https://docs.seleniumhq.org/download下載解壓至/usr/local/bin中(我使用的是Mac跨琳,windows和lunix好像是解壓至某路徑,并設(shè)置系統(tǒng)path桐罕。具體請(qǐng)百度)
  3. python所需包的安裝如下(我好像安裝完pytesseract就帶有pillow):
pip install selenium
pip install pytesseract
  • 構(gòu)造headers和data脉让,我建議是通過(guò)瀏覽器的開(kāi)發(fā)者工具將請(qǐng)求包拷貝為curl格式,這里面就包含了所有的信息功炮。
  • curl包含了請(qǐng)求包的所有信息溅潜,但是目前未找到方便的方法來(lái)提取并構(gòu)造為requests的headers和data格式,只好用手工構(gòu)造薪伏。
  • 在構(gòu)造headers時(shí)滚澜,因?yàn)椴恢绾稳ビ?jì)算'Content-Length',所以去掉了這一項(xiàng)嫁怀,對(duì)數(shù)據(jù)抓取沒(méi)有影響设捐,也就暫且不管。
  • 識(shí)別驗(yàn)證碼那一段塘淑,我基本上照抄這篇博客的:https://blog.csdn.net/weixin_38374974/article/details/80152899
  • 數(shù)據(jù)處理部分比較簡(jiǎn)單萝招,只是顯示抓到的數(shù)據(jù)包(json格式)和讀取其中某一項(xiàng)。

當(dāng)前只實(shí)現(xiàn)功能存捺,代碼尚未優(yōu)化槐沼。如下:

# -*- coding:utf-8 -*-
from selenium import webdriver
from PIL import Image, ImageEnhance
import pytesseract, time, re, requests, json


def getvalicode(driver):
    """
    獲取驗(yàn)證碼
    :param driver:
    :return: 返回驗(yàn)證碼,類型:str
    """
    driver.save_screenshot('./code/1.png')

    # 裁剪驗(yàn)證碼圖片捌治,并保存到文件中
    ran = Image.open("./code/1.png")
    box = (1490, 795, 1630, 850)    # 獲取驗(yàn)證碼位置,自動(dòng)定位不是很明白岗钩,就使用了手動(dòng)定位,代表(左肖油,上凹嘲,右,下)
    ran.crop(box).save('./code/2_1.png')

    # 處理驗(yàn)證碼圖片
    imagecode = Image.open('./code/2_1.png')
    sharp_img = ImageEnhance.Contrast(imagecode).enhance(2.0)  # 圖像增強(qiáng)构韵,二值化
    sharp_img.save("./code/2_2.png")
    sharp_img.load()  # 對(duì)比度增強(qiáng)

    # 識(shí)別驗(yàn)證碼
    # time.sleep(2)
    vcode = pytesseract.image_to_string(sharp_img)
    vcode = re.sub('[^0-9a-zA-Z]', '', vcode)
    print('驗(yàn)證碼:', vcode, end='\t')
    return vcode


def login(driver, url):
    """
    登陸系統(tǒng)
    :param driver:
    :param url:
    :return:True:登錄成功;False:登錄失敗
    """
    driver.get(url)
    # driver.implicitly_wait(15)
    driver.maximize_window()
    time.sleep(5)  # 等待瀏覽器打開(kāi)頁(yè)面

    vcode = getvalicode(driver)
    while len(vcode) != 4:
        driver.refresh()
        driver.maximize_window()
        time.sleep(5)  # 等待瀏覽器打開(kāi)頁(yè)面
        vcode = getvalicode(driver)

    # 獲取用戶名周蹭、密碼、驗(yàn)證碼疲恢、登錄按鍵
    username = driver.find_element_by_id('sAccount')
    userpwd = driver.find_element_by_id('sPasswd')
    valicode = driver.find_element_by_id('sValidataCode')
    login_button = driver.find_element_by_id('LoginButton')

    # 設(shè)置用戶帳號(hào)密碼
    username.clear()
    username.send_keys('****')
    userpwd.clear()
    userpwd.send_keys('*******')
    valicode.clear()
    valicode.send_keys(vcode)
    time.sleep(1)
    login_button.click()
    time.sleep(10)

    return driver.title == '*****'  # 此處通過(guò)頁(yè)面的title是否為某個(gè)字段來(lái)判斷是否登錄成功


def getcookie(driver):
    """
    獲取cookies
    :param driver:
    :return: 返回cookie 類型是str
    """
    cookies = driver.get_cookies()
    cookie = cookies[0]['name'] + '=' + cookies[0]['value']
    return cookie


def makeheaders(driver):
    """
    構(gòu)建Headers 可通過(guò)開(kāi)發(fā)者工具中的請(qǐng)求包獲刃桌省(建議使用將該請(qǐng)求包拷貝為curl格式,curl格式包含了header显拳、param棚愤、data)
    :param driver:
    :return: headers
    """
    cookie = getcookie(driver)
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'Origin': 'http://******',
        'Host': '*****',
        'Accept': 'text/plain, */*; q=0.01',
        'Connection': 'keep-alive',
        'Accept-Language': 'zh-cn',
        'Accept-Encoding': 'gzip, deflate',
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15',
        'Referer': 'http://********/index.jsp?urlPKIGuid=1535609520181',
        # 'Content-Length':287,
        'X-Requested-With': 'XMLHttpRequest',
        'Cookie': cookie
    }
    return headers


def makeurldata():
    """
    構(gòu)建請(qǐng)求包中的data
    :return:
    """
    urldata = json.dumps({'44-F0-FF-78-F4-25': {'2120001': ['221200190010', '231200020010']}})  # {'局站編碼':{'采集器編碼':['信號(hào)編碼','']}}
    return urldata


def getdata(headers, urldata):
    """
    獲取數(shù)據(jù)
    :param headers: 請(qǐng)求包頭
    :param urldata: 請(qǐng)求包的data
    :return: 
    """
    url = 'http://*********!getRuntimeData.action'
    session = requests.Session()
    r = session.post(url, headers=headers, data={'SU': urldata})
    a = r.json()
    print(a, '\n*************')
    for i in a:
        for j in i:
            print(i[j]['MeasuredVal'])


def main():
    url = 'http://*****/login.jsp'
    try:
        driver = webdriver.Firefox()
        # 重復(fù)嘗試登錄
        islogined = login(driver, url)
        while not islogined:
            islogined = login(driver, url)
        print('\n', driver.title, '成功登錄!')
        # 讀取數(shù)據(jù)
        headers = makeheaders(driver)
        urldata = makeurldata()
        getdata(headers, urldata)
    finally:
        driver.close()


if __name__ == '__main__':
    main()

如果本文對(duì)您有幫助,請(qǐng)給我留個(gè)言宛畦。謝謝瘸洛!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市次和,隨后出現(xiàn)的幾起案子反肋,更是在濱河造成了極大的恐慌,老刑警劉巖踏施,帶你破解...
    沈念sama閱讀 222,946評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件石蔗,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡畅形,警方通過(guò)查閱死者的電腦和手機(jī)养距,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)日熬,“玉大人棍厌,你說(shuō)我怎么就攤上這事∈” “怎么了定铜?”我有些...
    開(kāi)封第一講書人閱讀 169,716評(píng)論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)怕敬。 經(jīng)常有香客問(wèn)我揣炕,道長(zhǎng),這世上最難降的妖魔是什么东跪? 我笑而不...
    開(kāi)封第一講書人閱讀 60,222評(píng)論 1 300
  • 正文 為了忘掉前任畸陡,我火速辦了婚禮,結(jié)果婚禮上虽填,老公的妹妹穿的比我還像新娘丁恭。我一直安慰自己,他們只是感情好斋日,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,223評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布牲览。 她就那樣靜靜地躺著,像睡著了一般恶守。 火紅的嫁衣襯著肌膚如雪第献。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,807評(píng)論 1 314
  • 那天兔港,我揣著相機(jī)與錄音庸毫,去河邊找鬼。 笑死衫樊,一個(gè)胖子當(dāng)著我的面吹牛飒赃,可吹牛的內(nèi)容都是我干的利花。 我是一名探鬼主播,決...
    沈念sama閱讀 41,235評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼载佳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼炒事!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蔫慧,我...
    開(kāi)封第一講書人閱讀 40,189評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤挠乳,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后藕漱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體欲侮,經(jīng)...
    沈念sama閱讀 46,712評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡崭闲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,775評(píng)論 3 343
  • 正文 我和宋清朗相戀三年肋联,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刁俭。...
    茶點(diǎn)故事閱讀 40,926評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡橄仍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出牍戚,到底是詐尸還是另有隱情侮繁,我是刑警寧澤,帶...
    沈念sama閱讀 36,580評(píng)論 5 351
  • 正文 年R本政府宣布如孝,位于F島的核電站宪哩,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏第晰。R本人自食惡果不足惜锁孟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,259評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茁瘦。 院中可真熱鬧品抽,春花似錦、人聲如沸甜熔。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,750評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)腔稀。三九已至盆昙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間焊虏,已是汗流浹背弱左。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,867評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留炕淮,地道東北人拆火。 一個(gè)月前我還...
    沈念sama閱讀 49,368評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親们镜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子币叹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,930評(píng)論 2 361