爬蟲—暴力查詢快遞100

平時我們都會用查詢快遞都會用到 快遞100
今天試了一下用requests模擬該網(wǎng)站ajax請求查詢物流信息,發(fā)現(xiàn)概率性的返回不了結(jié)果,但是網(wǎng)站里手動查詢卻是ok的,so what?我也不知道咋回事。干脆換個暴力點的方法,selenium,優(yōu)點:完全模仿瀏覽器操作,所見即可爬(音頻文件除外),缺點:稍微有點慢。直接上代碼

1、構(gòu)建browser對象
此處選擇 PhantomJS 無界面瀏覽器,雖然selenium官方已經(jīng)打算放棄該瀏覽器了,但是目前還能用,個人覺得很好用。

先構(gòu)建一個PhantomJS的瀏覽器對象,再設(shè)置一個顯式等待

class A():

    # 構(gòu)建browser對象
    _url="https://www.kuaidi100.com/"
    browser = selenium.webdriver.PhantomJS()
    wait = WebDriverWait(browser, 10)                          # 設(shè)置顯式等待
    browser.get(_url)

2、模擬瀏覽器端快遞查詢,獲取查詢到的網(wǎng)頁源碼

網(wǎng)頁端

   @classmethod
   def get_page_source(cls, code):
       """
       獲取快遞查詢頁網(wǎng)頁源碼
       :param code:
       :return: 網(wǎng)頁源碼或者False
       """
       try:
           # 獲取快遞單號輸入框
           input = cls.wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "#postid")))
           # 獲取查詢按鈕
           s = cls.wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, "#query")))
           # 先清空快遞單號輸入框,在輸入快遞單號
           input.clear()
           input.send_keys(code)
           # 點擊查詢
           s.click()
           time.sleep(1)
           # 是否查詢到物流信息,查詢成功返回網(wǎng)頁源碼,并關(guān)閉瀏覽器,騰出資源
           try:
               # 預(yù)查詢數(shù)據(jù),查看窗口元素
               cls.browser.find_element_by_css_selector("table.result-info")
               result_flag = True
           except:
               result_flag = False
           if result_flag:
               html = cls.browser.page_source
               cls.browser.close()
               return html
           # 未查詢到記錄
           no_find = cls.browser.find_element_by_id("notFindTip")
           if no_find:
               print("暫無查詢記錄")
               return False
           # 查詢時發(fā)生錯誤
           error_message=cls.browser.find_element_by_id("errorMessage")
           if error_message:
               print(error_message.text)
               return False
           return False
       
       # 捕獲一些異常,避免程序崩掉
       except Exception as e:
           print("error: ", e)
           return False

3、解析網(wǎng)頁源碼,獲取目標(biāo)數(shù)據(jù)

    @classmethod
    def parse_page_source(cls, html):
        # 用pyquery解析網(wǎng)頁源碼
        pq=pyquery.PyQuery(html)
        # 獲取物流信息網(wǎng)頁元素
        items = pq("#queryResult > div.result-wrap > div.relative.query-box > table > tbody > tr")
        # 依次迭代獲取到的物流信息網(wǎng)頁元素
        for i in items.items():
            # 獲取時間信息
            t = i("td.row1").text()
            # 將星期數(shù)標(biāo)準(zhǔn)化
            weekend=cls.generate_weekend(t[0:10])
            # 將時間格式標(biāo)準(zhǔn)化
            t = t[0:10] + '\t' + t[10:15] + '\t' + weekend
            # 獲取物流狀態(tài)
            status = i("td:last-child").text()
            print(t.ljust(25), status.ljust(1))

    @classmethod
    def generate_weekend(cls, date_str):
        list = ['一', '二', '三', '四', '五', '六', '日']
        weekend = datetime.datetime.strptime(date_str, "%Y.%m.%d").isoweekday()
        weekend = "星期" + dict(enumerate(list, 1)).get(weekend)
        return weekend

4、將相關(guān)函數(shù)進(jìn)行封裝

以下是整個程序源代碼以及運行結(jié)果

import time
import pyquery
import datetime
import selenium.webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ec


class A():
    # 構(gòu)建browser對象
    _url = "https://www.kuaidi100.com/"
    browser = selenium.webdriver.PhantomJS()
    wait = WebDriverWait(browser, 10)
    browser.get(_url)

    @classmethod
    def do(cls):
        code = input("輸入快遞單號: ")
        ret = cls.get_page_source(code)
        if not ret:
            return ret
        cls.parse_page_source(ret)

    @classmethod
    def get_page_source(cls, code):
        """
        獲取快遞查詢頁網(wǎng)頁源碼
        :param code:
        :return: 網(wǎng)頁源碼或者False
        """
        try:
            # 獲取快遞單號輸入框
            input = cls.wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "#postid")))
            # 獲取查詢按鈕
            s = cls.wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, "#query")))
            # 先清空快遞單號輸入框,在輸入快遞單號
            input.clear()
            input.send_keys(code)
            # 點擊查詢
            s.click()
            time.sleep(1)
            # 是否查詢到物流信息,查詢成功返回網(wǎng)頁源碼,并關(guān)閉瀏覽器,騰出資源
           try:
                # 預(yù)查詢數(shù)據(jù),查看窗口元素
                cls.browser.find_element_by_css_selector("table.result-info")
                result_flag = True
            except:
                result_flag = False
            if result_flag:
                html = cls.browser.page_source
                cls.browser.close()
                return html
            # 未查詢到記錄
            no_find = cls.browser.find_element_by_id("notFindTip")
            if no_find:
                print("暫無查詢記錄")
                return False
            # 查詢時發(fā)生錯誤
            error_message = cls.browser.find_element_by_id("errorMessage")
            if error_message:
                print(error_message.text)
                return False
            return False

        # 捕獲一些異常,避免程序崩掉
        except Exception as e:
            print("error: ", e)
            return False

    @classmethod
    def parse_page_source(cls, html):
        # 用pyquery解析網(wǎng)頁源碼
        pq = pyquery.PyQuery(html)
        # 獲取物流信息網(wǎng)頁元素
        items = pq("#queryResult > div.result-wrap > div.relative.query-box > table > tbody > tr")
        # 依次迭代獲取到的物流信息網(wǎng)頁元素
        for i in items.items():
            # 獲取時間信息
            t = i("td.row1").text()
            # 將星期數(shù)標(biāo)準(zhǔn)化
            weekend = cls.generate_weekend(t[0:10])
            # 將時間格式標(biāo)準(zhǔn)化
            t = t[0:10] + '\t' + t[10:15] + '\t' + weekend
            # 獲取物流狀態(tài)
            status = i("td:last-child").text()
            print(t.ljust(25), status.ljust(1))

    @classmethod
    def generate_weekend(cls, date_str):
        list = ['一', '二', '三', '四', '五', '六', '日']
        weekend = datetime.datetime.strptime(date_str, "%Y.%m.%d").isoweekday()
        weekend = "星期" + dict(enumerate(list, 1)).get(weekend)
        return weekend


if __name__ == "__main__":
    A.do()

>>>
輸入快遞單號: YT4031232184872
2019.08.18  15:16   星期日      客戶 簽收人: 已簽收,簽收人憑取貨碼簽收。 已簽收 感謝使用圓通速遞,期待再次為您服務(wù)
2019.08.17  09:33   星期六      快件已暫存至西安糜家橋西門店菜鳥驛站,如有疑問請聯(lián)系18502974450
2019.08.17  08:10   星期六      【陜西省西安市高科廣場公司】 派件人: xxx 派件中 派件員電話18220687549
2019.08.17  07:52   星期六      【陜西省西安市高科廣場公司】 已收入
2019.08.16  20:32   星期五      【西安轉(zhuǎn)運中心】 已發(fā)出 下一站 【陜西省西安市高科廣場公司】
2019.08.16  19:37   星期五      【西安轉(zhuǎn)運中心】 已收入
2019.08.16  00:22   星期五      【成都轉(zhuǎn)運中心】 已發(fā)出 下一站 【西安轉(zhuǎn)運中心】
2019.08.16  00:08   星期五      【成都轉(zhuǎn)運中心】 已收入
2019.08.14  20:52   星期三      【四川省直營市場部】 已發(fā)出 下一站 【成都轉(zhuǎn)運中心】
2019.08.14  20:52   星期三      【四川省直營市場部公司】 已收件

Process finished with exit code 0
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容