Python爬蟲:細說列表識別提取

天冷要保暖

??上次文章后不少小伙伴私信我,對此感興趣缓淹,希望我講講列表識別的細節(jié)問題哈打。于是有了今天這篇文章。還是先再提一下本算法的核心思想讯壶。

  • 排列規(guī)則的鏈接為可以列表塊料仗。
  • 列表塊范圍在主視圖區(qū)域內為目標列表。
    先看下識別結果:
    列表識別結果圖

    提取列表區(qū)域xpath宏觀分成三個大步驟

1.可疑列表區(qū)域提取

??在進行可疑列表區(qū)域提取之前需要做一些預處理:因為selenium只能定位到頁面上的可見元素伏蚊,所以先用selenium的find_elements_by_xpath("http://a")獲取所有可見的<a>立轧,并對定位到的元素創(chuàng)建新屬性canSee并賦值yeap:self.__web_driver.execute_script("arguments[0].setAttribute('can-see','yeap');", link)(其實你想屬性叫什么就叫什么),然后就清洗完畢了丙挽。
??接下來用lxml庫的etree定位到dom樹(這里將html直接說成dom樹是為了后面提取最小父節(jié)點時候好理解)上所有canSee屬性是True的<a>標簽節(jié)點肺孵。將該節(jié)點假如列表A,以三個元素為單位掃描該列表颜阐,如下圖平窘。

可疑列表區(qū)域掃描過程示意圖

Tips:
  • 在整個dom樹下,同一子樹同一層級的節(jié)點才會提取最小父節(jié)點(最小父節(jié)點:層級盡可能的小
  • 重復父節(jié)點的xpath不要重復計入
  • 有的<a>標簽下取text會出現(xiàn)問題凳怨,最好用xpath的string(.)方式
  • 元素清洗時可以初步匹配明顯反向特征瑰艘,匹配成功直接退出

??在三大步驟中,只有這一步是在做加法肤舞,剩下的步驟基本是在過濾做減法了紫新,所以盡可能的將可疑列表區(qū)域收入列表。

代碼流程參考:
def tag_a_min_father_node(self):
    """
    計算提取可疑列表區(qū)域        
    :return: [xpath1,xpath2,xpath3,...]
    """
    links_Ele = []
    father_list = []
    # 預處理-將可見<a>設置屬性can-see
    self.watch_links()

    root = etree.HTML(self.driver.page_source)
    Eleroot = etree.ElementTree(root)
    temp_total_path = []
    links =  Eleroot.findall('//a[@cansee]')
    self.LOG.info("all links after filter: {}".format(len(links)))
    # 識別時忽略JavaScript李剖,因為后續(xù)步驟沒有上下文環(huán)境
    links_Ele = [(x.xpath("string(.)")..strip(),\
                  Eleroot.getpath(x), \
                  x.attrib.get("href","")) \
                  for x in links \
                  if x.xpath("string(.)"). and len(x.xpath("string(.)").strip()) > 1 and \
                       self.anchor_black_regx.search(x.xpath("string(.)").strip()) is None\
                      and self.debar_extension_name_regex.search(x.attrib.get("href","")) is None \
                      and not x.attrib.get("href","").startswith("java")\
                      and not x.attrib.get("href","").startswith("#") # 不要錨鏈接
                     ]
    # 元素清洗
    # 相鄰標簽相同href芒率,合并
    # 如果匹配到反向特征 legitimate = False
    legitimate, links_Ele = self.clean_links_Ele(links_Ele)

    if legitimate:
        # 掃描有效鏈接,提取最小父節(jié)點xpath
        for idx in xrange(len(links_Ele)-2):
            # 每次取三個元素
            now = links_Ele[idx: idx+3]
            is_list, father_xpath = self.get_list_father_xpath(now)
            if is_list:
                # 符合列表邏輯
                father_list.append(father_xpath)

    return list(set(father_list))

2.過濾不在主視圖區(qū)域的可疑列表

  • 2.1 校驗x軸
    ??在這該步驟中篙顺,校驗可疑列表區(qū)域是否在主視圖范圍內偶芍。你需要了解selenium的location方法充择,了解(x,y)坐標點在瀏覽器中的意義匪蟀,在該算法中椎麦,使用x軸中位線作為判斷依據(jù)。
    ??現(xiàn)有列表區(qū)域A,其location為(x1,y1)材彪。列表A中观挎,有最大鏈接b,其size['width']為x2段化。若x1+x2 > x軸中位線嘁捷,則列表A在主視圖范圍內。
    ??看下圖穗泵,不難理解:
    紅線為x軸中位線

代碼流程參考:

def judge_list_xpath(self):
    """
    判斷獲取到的列表xpath是否在主視圖區(qū)域
    :return:[xpath1,xpath2]
    """
    a_list= []
    list_xpath = []
    result = []
    # 獲取可疑列表區(qū)域
    list_xpath = self.get_page_list()

    if list_xpath:
        for item in list_xpath:
            a_size_list = []
            try:
                a_list = self.driver.find_elements_by_xpath(item + '//a')
            except:
                self.LOG.error("{}:{}無法找到該xpath" .format(self.driver.current_url, item + '//a'))

            for element in a_list:
                a_size_list.append(element.size['width'])
            # 有的html可能不規(guī)范普气,會出現(xiàn)定位不到元素的情況
            max_a_size = max(a_size_list) if len(a_size_list) > 0 else 0
            if max_a_size == 0: continue
            # 判斷size最大的a標簽的位置
            content = self.driver.find_element_by_xpath(item)
            # 超過3000認為異常情況
            if content.size['width'] > 3000:
                continue
            # 這句無所謂,原來想用來過濾導航欄之類的佃延,現(xiàn)在后續(xù)有更好解決方案
            if (content.size['height']) < 70 and content.size['height'] != 0:
                continue
            # 判斷x軸中位線
            if self.check_x(content):
                    result.append(item)
    self.LOG.info("list after view filter: {}".format(result))
    return result
  • 2.2校驗y軸
    ??這一步需要放在程序最后,規(guī)則也比較簡單夷磕,最后校驗列表的location['y']是否在瀏覽器的當前頁面中履肃,我認為如果你打開網(wǎng)頁,一下看不見列表坐桩,需要往下拖才有列表尺棋,就不是我們需要的主列表了,可能是混進來奇奇怪怪的東西绵跷,邏輯比較簡單就不貼代碼流程了膘螟。

3.可擴展規(guī)則簇

??以上步驟基本可以保證你獲得一個穿過了x中位線的列表區(qū)域,但極有可能混進去一些奇奇怪怪的東西碾局,或者漏了一些重要的東西荆残。這時候就需要你的這些規(guī)則了,比如:

  • 多塊列表跨x中位線
  • 識別到導航欄或者識別到滾動欄中的新聞俘闯,不需要這種東西,需要過濾
    • 過濾規(guī)則很簡單忽冻,校驗xpath中<a>的y坐標真朗,極大值與極小值需要超過一個閥值
  • 中央?yún)^(qū)域含有文本為更多的鏈接,我相信這種列表也不是我們需要的
    還有后續(xù)其他的規(guī)則往上追加就好OvO

至此列表區(qū)域識別已經(jīng)完成僧诚,輸出值為列表區(qū)域的xpath遮婶。
有問題的話私聊我吧蝗碎,沒問題的話點贊吧~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蹭睡,隨后出現(xiàn)的幾起案子衍菱,更是在濱河造成了極大的恐慌,老刑警劉巖肩豁,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脊串,死亡現(xiàn)場離奇詭異,居然都是意外死亡清钥,警方通過查閱死者的電腦和手機琼锋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來祟昭,“玉大人缕坎,你說我怎么就攤上這事〈畚颍” “怎么了谜叹?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長搬葬。 經(jīng)常有香客問我荷腊,道長,這世上最難降的妖魔是什么急凰? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任女仰,我火速辦了婚禮,結果婚禮上抡锈,老公的妹妹穿的比我還像新娘疾忍。我一直安慰自己,他們只是感情好床三,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布一罩。 她就那樣靜靜地躺著,像睡著了一般勿璃。 火紅的嫁衣襯著肌膚如雪擒抛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天补疑,我揣著相機與錄音歧沪,去河邊找鬼。 笑死莲组,一個胖子當著我的面吹牛诊胞,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼撵孤,長吁一口氣:“原來是場噩夢啊……” “哼迈着!你這毒婦竟也來了?” 一聲冷哼從身側響起邪码,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤裕菠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后闭专,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奴潘,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年影钉,在試婚紗的時候發(fā)現(xiàn)自己被綠了画髓。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡平委,死狀恐怖奈虾,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情廉赔,我是刑警寧澤肉微,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站蜡塌,受9級特大地震影響浪册,放射性物質發(fā)生泄漏。R本人自食惡果不足惜岗照,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望笆环。 院中可真熱鬧攒至,春花似錦、人聲如沸躁劣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽账忘。三九已至志膀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鳖擒,已是汗流浹背溉浙。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蒋荚,地道東北人戳稽。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像期升,于是被迫代替她去往敵國和親惊奇。 傳聞我的和親對象是個殘疾皇子互躬,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351