python之selenium的坑总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012111465/article/details/80644105

最近锁王唐唐很厉害啊,甚是迷恋,鄙人观望了小呆的微博已经两天了,路转粉,绝对铁粉,闲来无事,我要开始分析wuli唐唐了。爬取了小呆的新浪微博,赞帖,帖子内容,发帖时间,转发数,评论数,点赞数。其中,不乏入坑无数,然而,都一一克服了,不得不说,这就是小呆的力量。

模拟人类自动登录记住cookie

捕获当前所有窗口

在这里,不得不说,新浪微博的爬取并非易事。
首先,进入”https://weibo.com/”的登录页面,自动化介入,点击“登录”的同时,网页跳转了,此时,需要捕捉当前所有窗口。

handles = browser.window_handles  #获取当前打开的所有窗口的句柄

页面跳转/窗口切换

捕获全部窗口,锁定当前窗口。

browser.switch_to.window(handles[1])  #切换到第二个窗口的句柄
print(browser.current_window_handle)
print(browser.current_url)

iframe窗口解决自动登录

经过无数次xpath的元素定位查找,总是出现NoSuchElementException,并未能解决,经过查阅大量资料,无意中发现iframe类型,查看原码,发现该登陆窗口是iframe形式,大喜!
这里写图片描述
这里写图片描述
这里写图片描述

browser.implicitly_wait(5)
#先找到到iframe(id )
browser.switch_to_frame("ptlogin_iframe")
browser.find_element_by_xpath('//*[@id="qlogin_list"]/a[1]').click()

定位并点击进行登陆,需要说明,这里我是通过扣扣注册的新浪微博,同时需要把扣扣登陆上。
这里写图片描述

搜索框自动搜索

定位并点击搜索,接下来就是一些列的自动click,直到进入目标任务的主页。

browser.implicitly_wait(5)
search = browser.find_element_by_xpath('//*[@id="plc_top"]/div/div/div[2]/input').send_keys("唐禹哲")
browser.find_element_by_xpath('//*[@id="plc_top"]/div/div/div[2]/a').click()

这里写图片描述

需要保留cookie的保留,下次直接cookie就可以。
同时,在爬取过程中,页面加载可能需要时间,此时,需要设置等待时间。

异步加载

新浪微博的页面比较特殊,需要大概三次拖拽方可将第一页加载完全,其他页也是一样,找了很多selenium异步加载的文章都未能解决问题,直到遇到下面的解决方案。何为异步加载,当滑到底部,页面出现待加载的内容。
这里写图片描述

time.sleep(10)

def selenuim_loading_more(browser, method_index=0): 
  if method_index==0: 
    browser.implicitly_wait(3) # 为了快速滑动,先设置超时时间为3秒 
    # while True: 
    for i in range(1, 4): # at most 3 times 
      print("loading more, window.scrollTo bettom for the", i,"time ...")
      browser.execute_script("window.scrollTo(0,document.body.scrollHeight);") 
      try: 
        # 定位页面底部的换页tab 
        browser.find_element_by_css_selector("div[class='W_pages']") 
        break # 如果没抛出异常就说明找到了底部标志,跳出循环 
      except : 
        pass # 抛出异常说明没找到底部标志,继续向下滑动 
    browser.implicitly_wait(4) # 将超时时间改回10秒 
  elif method_index==1: 
    browser.find_element_by_css_selector("div[class='empty_con clearfix']").click() # loading more 
    print("loading more, sleep 4 seconds ... 1")
    time.sleep(4) 
    browser.find_element_by_css_selector("div[class='empty_con clearfix']").click() # loading more 
    print("loading more, sleep 3 seconds ... 2")
    time.sleep(2) 
  elif method_index==2: 
    load_more_1 = browser.find_element_by_css_selector("div[class='empty_con clearfix']") # loading more         
    ActionChains(browser).click(load_more_1).perform() 
    print("loading more, sleep 4 seconds ... 1")
    time.sleep(4) 
    load_more_2 = browser.find_element_by_css_selector("div[class='empty_con clearfix']") # loading more         
    ActionChains(browser).click(load_more_2).perform() 
    print("loading more, sleep 3 seconds ... 2") 
    time.sleep(2) 
  elif method_index==3: 
    print("loading more, sleep 4 seconds ... 1") 
    element = WebDriverWait(browser, 4).until( 
      EC.element_to_be_clickable((By.CSS_SELECTOR, "div[class='empty_con clearfix']")) 
    ) 
    element.click() 
    print("loading more, sleep 2 seconds ... 2") 
    WebDriverWait(browser, 2).until( 
      EC.element_to_be_clickable((By.CSS_SELECTOR, "div[class='empty_con clearfix']")) 
    ).click() 
  return browser 

browser = selenuim_loading_more(browser, method_index=0) 

ok !异步加载问题的解决就真的解决了多数了,下面就是元素定位问题。

selenium元素定位

最简单的额一种方法就是通过选定找到xpath,而xpath的语法又有很多种,
第一种是通过制定contains

 browser.find_elements_by_xpath('//div[contains(@class,"WB_info")]//a[contains(@href,"//weibo.com/")]')

第二种是全部路径形式

browser.find_element_by_xpath('//*[@id="Pl_Official_MyProfileFeed__21"]/div/div[{0}]/div[2]/div/ul/li[2]/a/span/span/span/em[2]'.format(i+1))

这样的话,可能是点赞的文章与自己发的帖子的xpath路径不同,就需要设置判断语句来进行不同的操作。
其他方法也有很多,这里就用了两种,其他方法,自行搜索。

异常报错判断

在爬虫过程中,需要增加相应的异常判断,否则,爬了半天,发现最后报错了,那就简直*了狗了,心中一万只你懂得!
常用的异常判断,无非就是try except

from requests.exceptions import ReadTimeout,HTTPError,ConnectionError,RequestException
from selenium.common.exceptions import NoSuchElementException

try:
    weibo_content.append(browser.find_element_by_xpath('//*[@id="Pl_Official_MyProfileFeed__21"]/div/div[{0}]/div[2]/div[3]/div[4]'.format(i+1)).text)

except NoSuchElementException:
    weibo_content.append(browser.find_element_by_xpath('//*[@id="Pl_Official_MyProfileFeed__21"]/div/div[{0}]/div[2]/div[4]/div[4]'.format(i+1)).text)

这里也就列举了几种,其他的需要自己查阅。

展开阅读全文

没有更多推荐了,返回首页