当前位置:   article > 正文

python爬虫笔记(五)——动态网页处理(下篇)_profile.managed_default_content_settings.images

profile.managed_default_content_settings.images

前面总结了通过寻找后台接口来爬取动态网页,这篇博客总结一下selenium+chrome如何爬取动态页面,selenium现在貌似不在支持PhantomJs,python版本为3.6

 

Xpath的/与//的不同:/是在它的子结点中查找,而//是在它的所有子结点中查找,包括子结点的子结点等等

 

1、安装chromedriver

网址:http://chromedriver.chromium.org/downloads(需要翻墙)

请安装与自己chrome版本(在浏览器地址栏输入chrome://settings/help可查看)一致的chromedriver

下载完后,将chromedriver的所有文件拖到chrome的安装文件夹,设置到chrome安装文件夹的环境变量(方便代码处理)

 

2、查看selenium官方文档

网址:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.chrome.webdriver

常用函数总结一下:

  1. #selenium.webdriver.chrome.webdriver.WebDriver
  2. __init__:第一个形参用于指定chromedriver的路径,如果不指定,使用
  3. 环境变量path下的路径,第二个参数指定运行端口号,如果不指定,随便选择一个空端口号
  4. quite():关闭浏览器
  1. #selenium.webdriver.chrome.options.Options
  2. 用于设置chrome浏览器,目前使用过的参数:
  3. 1、阻止chrome弹窗的出现:'profile.default_content_setting_values' :{'notifications' : 2}
  4. 2、不加载图片:"profile.managed_default_content_settings.images":2
  5. 3、无头浏览器,--headless
  6. add_experimental_option(name, value):将设置参数传递给chrome
  1. #selenium.webdriver.remote.webdriver.WebDriver
  2. close():关闭当前窗口
  3. execute_async_script():异步执行js代码
  4. execute_script():同步执行js代码
  5. quit():关闭驱动以及所有窗口
  6. get(url):获得某个页面
  7. set_window_size(width, height, windowHandle='current'):设置窗口大小
  8. maximize_window():窗口最大化
  9. page_source属性,获得当前页面的html代码
  10. driver.execute_script("window.scrollTo(0, document.body.scrollHeight);":执行翻页
  11. find_element_by_id:全文查找,根据完整的id值查找,返回selenium.webdriver.remote.webelement.WebElement对象
  12. find_element_by_class_name:全文查找,根据完整的class值查找,返回selenium.webdriver.remote.webelement.WebElement对象
  13. find_element_by_xpath(xpath):全文查找,根据xpath查找,返回selenium.webdriver.remote.webelement.WebElement对象
  1. #selenium.webdriver.remote.webelement.WebElement
  2. click():点击按钮
  3. find_element_by_id:根据id查找,返回selenium.webdriver.remote.webelement.WebElement对象,只查找子元素
  4. find_element_by_class_name:根据class name查找,返回selenium.webdriver.remote.webelement.WebElement对象,只查找子元素
  5. find_element_by_xpath(xpath):根据xpath查找,返回selenium.webdriver.remote.webelement.WebElement对象,只查找子元素
  6. submit():提交表单
  7. send_keys():填值
  8. text属性:该元素的文本值

3、常见异常

NoSuchElementException

关于起因,我总结了两点:

1、页面元素未被加载出来,这里有两种可能

第一、等待时间过短,导致元素未加载

第二、浏览器窗口不够大,导致页面元素未加载,此时不论等待多长时间都没用,因此,每次都要将窗口设置为最大值

2、寻找元素的标记本身发生错误

 

4、实例

爬取迪丽热巴的微博发言,由于是练习,因此会有一些不必要的步骤

 

引入的包:

  1. from selenium import webdriver
  2. import time
  3. from lxml import etree

 

1、实例化webdriver

  1. options = webdriver.ChromeOptions()
  2. prefs = {
  3. 'profile.default_content_setting_values' :
  4. {
  5. 'notifications' : 2
  6. },
  7. "profile.managed_default_content_settings.images":2
  8. }
  9. options.add_experimental_option('prefs',prefs)
  10. driver = webdriver.Chrome(chrome_options = options)
  11. driver.maximize_window()

禁止chrome弹窗(注意是chrome自带的弹窗,不是网站的弹窗)、不加载图片

 

2、登陆微博

 

注意到弹窗的存在,如果不设置,chrome就会有弹窗,但是不妨碍处理网页

登陆用户具有更多的浏览权限,因此需要登陆

  1. def login_weibo():
  2. driver.get('https://weibo.com/')
  3. time.sleep(10)
  4. element=driver.find_element_by_id('loginname')
  5. element.send_keys('你的账号名')
  6. element=driver.find_element_by_name('password')
  7. element.send_keys('你的密码')
  8. element=driver.find_element_by_class_name('W_btn_a')
  9. element.click()

这里有一个坑,如果不最大化窗口,微博首页的登陆框是不会出现的(google、百度了一堆,没啥用,然后才发现这么回事.....

这个登陆方式不是很完善,没有验证码的处理,但验证码并不常见(尝试登陆了几十次,没见过验证码.......),所以就不写了,出现验证码可以尝试用OCR的识别手段,也可以考虑自己手工输入

 

3、在搜索框搜索迪丽热巴并点击

 

 

  1. def search_weibo():
  2. #查找搜索框并输入信息
  3. elements=driver.find_elements_by_class_name('W_input')
  4. elements[0].send_keys('迪丽热巴')
  5. #点击搜索按钮
  6. element=driver.find_element_by_class_name('ficon_search')
  7. element.click()
  8. time.sleep(10)
  9. #进入迪丽热巴的微博
  10. element=driver.find_element_by_class_name('name_txt')
  11. element.click()
  12. time.sleep(10)

这里设置了等待时间,因为整个页面的加载速度奇慢,如果等待时间不足,可能相应的元素就无法加载

 

4、选在查看全部微博

这个权限在登陆后才有

  1. def select_all():
  2. #定位最新打开的窗口
  3. windows = driver.window_handles
  4. driver.switch_to.window(windows[-1])
  5. #选择全部按钮,点击
  6. element=driver.find_element_by_xpath("//li[@class='tab_li tab_li_first']/a")
  7. element.click()
  8. time.sleep(10)

这里有个坑,如果我们用selenium让chrome打开了多个窗口,chrome的webdriver不会定位到最新的窗口,而是一直处于第一个窗口,所以前两行代码用于定位最新打开的窗口

 

5、爬取前三页微博信息

  1. def crawel():
  2. i=0
  3. while(i!=3):
  4. #翻页
  5. driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
  6. time.sleep(5)
  7. #使用etree查看是否有下一页元素
  8. page=driver.page_source
  9. html_parse=etree.HTML(page)
  10. a=html_parse.xpath("//a[@class='page next S_txt1 S_line1']")
  11. #存在下一页元素,此时该页全部加载完毕,爬取
  12. if a!=[]:
  13. text_list=html_parse.xpath("//div[@class='WB_text W_f14']")
  14. for index in range(0,len(text_list)):
  15. result=text_list[index].text.replace(' ','').replace('\n','')
  16. if result!='':
  17. file.write(result+'\n')
  18. element=driver.find_element_by_class_name('next')
  19. element.click()
  20. i=i+1

微博需要下拉一定长度才会出现下一页的标签,在网上查找了许多下拉网页的方式都没用,最后查阅官方文档才找到答案:

driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")

lxml元素选择器的处理速度比selenium快很多,查找不到也不会抛异常,因此,寻找下一页元素我选择使用lxml(网页要下拉到最底才会出现下一页标识符,未出现下一页标识符,selenium会抛异常),这里没有处理因网络原因导致的重新加载情况

 

6、部分执行结果(CSDN不知咋回事,只能丢出这么点文本)

  1. 果然,最喜欢夏天
  2. 自从这个妹妹出道以后老学我
  3. 希望平安无事
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/458002
推荐阅读
相关标签
  

闽ICP备14008679号