在入了python爬虫的坑之后….继两个月前网易大佬问我你怎么解决异步加载的网页爬虫问题….最近终于学习了一下新知识解决了这个问题….
之前一直是用request库,监听network和js请求来找到想要的加载…当然现在看了一个厉害的东西叫selenuim…果断入坑
selenuim本来是一个测试型的第三方库…但是用在爬虫上它的作用极其强大….其实就是模拟点击或者之类的操作而已…这样可以解决需要找请求包或者是解析js之类的繁琐事情
————————————————————————————————————————————————
当然安装之类的过程就跳过了….需要安装的是selenuim库和网上下载一个对应chrome版本的chromedriver.exe放到python/script/目录下就可以了
1.定义一个driver对象
正常定义的方式和chrome无头定义方式,如果使用注释里的三行定义对象的话,是不会出现图形界面的
driver = webdriver.Chrome()# opt = webdriver.ChromeOptions()# opt.set_headless()# driver = webdriver.Chrome(options=opt)
2.对对象的cookies初始化
跟使用变量一样,虽然不进行初始化也可以,但是进行初始化总归是一个好的代码习惯,在清除cookies后,跳转到目标界面
driver.delete_all_cookies()driver.get(start_url)
3.登录
爬腾讯的网站最大的问题就是登录…因为不能像入门时的简单的发出登录请求包,获取cookies后再用cookies来访问,因为先不说腾讯的界面每次访问都需要登录,并且减少了cookies的生命周期,当你的浏览器关闭后,再次登录就不能使用之前的cookies了…就算没有这个问题,腾讯的请求包又多内容又多…反正凭我的肉眼是实在懒得去找也不一定找得到具体内容…
所以selenuim的强大就体现在这里,不需要去找请求,直接模拟登录就可以了
QQ的登录有两种方式,一种是在你电脑上本身登录了QQ,使用点击头像快捷登录和正常的输入账号密码登录
当然首先我们先定位到登录的iframe框,减小定位误差,time.sleep的作用不用多说,防止闪电侠出错也可以防止被认为是爬虫
driver.switch_to.frame("login_frame") #进入登录iframetime.sleep(1);
1)点击头像快捷登录
这个很简单,我们完全可以知道点击的头像位置,然后在F12中找到对应的头像框的位置,然后右键获取这个框的xpath,然后直接使用driver.find_element_by_xpath()定位到这个位置并且.click()模拟点击,就可以做到快捷登录
如果不使用xpath,那么使用常规定位方式也是可以定位到这个位置的
比如使用driver.find_element_by_class(“face”)也是可以定位到这个位置的,如果为了定位准确,那么当然按层级定位自然会更加准确
driver.find_element_by_xpath('//*[@id=\"qlogin_list\"]/a[1]').click();time.sleep(1);
2)使用账号密码登录
使用账号密码登录的话自然就需要先切换到输入账号密码的页面,所以我们先通过id=”switcher_plogin”定位到切换账号密码登录,然后模拟点击,切换到账号密码登录界面后,输入账号密码并且点击登录
change = driver.find_element_by_id("switcher_plogin")change.click()driver.find_element_by_id('u').clear()#选择用户名框driver.find_element_by_id('u').send_keys(user)driver.find_element_by_id('p').clear()driver.find_element_by_id('p').send_keys(userpsw)driver.find_element_by_class_name("login_button").click()
当然做完以上步骤登录完成后,我们可以切换到主界面,来防止某种特殊情况下出错
driver.switch_to_default_content()
3.动态加载下拉界面
比如登录到QQ群成员界面,网页上显示的只有40个左右的人数,当网页下拉时,每次更新会加载20个成员的信息,但是显然我们要的肯定不会只是这40个人的信息,我们需要所有人的信息..那么我们需要模拟下拉界面…这时候selenuim另一个功能出现了…它可以在页面上运行js脚本
def scroll_foot(driver):js="var q=document.documentElement.scrollTop=100000"return driver.execute_script(js)def sroll_multi(driver,times=20,loopsleep=1):#40 titles about 3 timesfor i in range(times):time.sleep(loopsleep)print ("Scroll foot %s time..." % i)scroll_foot(driver)time.sleep(loopsleep)
js模拟每次拉到当前页面的地步,加载后继续重复步骤直到全部加载完成…至于需要加载多少次也很简单..我们只要直到群有多少个成员就可以了…群成员人数/20就是需要下拉的次数
4.获取整个页面源代码并写入文件
f = open("html.txt",'w',encoding='utf-8')f.write(driver.page_source)f.close()# print(driver.page_source)driver.quit()
5.以上就是每个部分的作用以及代码块
6.整体代码
import osimport timefrom selenium import webdriverdef scroll_foot(driver):if driver.name == "chrome":js="var q=document.documentElement.scrollTop=100000"return driver.execute_script(js)def sroll_multi(driver,times=20,loopsleep=1):#40 titles about 3 timesfor i in range(times):time.sleep(loopsleep)print ("Scroll foot %s time..." % i)scroll_foot(driver)time.sleep(loopsleep)def main(start_url,number):driver = webdriver.Chrome()# opt = webdriver.ChromeOptions()# opt.set_headless()# driver = webdriver.Chrome(options=opt)print("登录")driver.delete_all_cookies()driver.get(start_url)driver.switch_to.frame("login_frame") #进入登录iframetime.sleep(1);# driver.find_element_by_xpath('//*[@id=\"qlogin_list\"]/a[1]').click();# time.sleep(1);change = driver.find_element_by_id("switcher_plogin")change.click()driver.find_element_by_id('u').clear()#选择用户名框driver.find_element_by_id('u').send_keys(user)driver.find_element_by_id('p').clear()driver.find_element_by_id('p').send_keys(userpsw)driver.find_element_by_class_name("login_button").click()driver.switch_to_default_content()# print(driver.name)sroll_multi(driver,(int)((int)(number)/20 + 3))f = open("html.txt",'w',encoding='utf-8')f.write(driver.page_source)f.close()# print(driver.page_source)driver.quit()if __name__ == '__main__':# user=input("账号:")# userpsw=input("密码:")number = input("当前群人数:")url = input("url")main(url,number)
7.selenium的十八种定位方式
前八种是大家都熟悉的,经常会用到的
- id定位:findelement_by_id(self, id)
- name定位:find_element_by_name(self, name)
- class定位:find_element_by_class_name(self, name)
- tag定位:find_element_by_tag_name(self, name)
- link定位:find_element_by_link_text(self, link_text)
- partial_link定位find_element_by_partial_link_text(self, link_text)
- xpath定位:find_element_by_xpath(self, xpath)
- css定位:find_element_by_css_selector(self, css_selector)
这八种是复数形式
- id复数定位findelements_by_id(self, id)
- name复数定位find_elements_by_name(self, name)
- class复数定位find_elements_by_class_name(self, name)
- tag复数定位find_elements_by_tag_name(self, name)
- link复数定位find_elements_by_link_text(self, text)
- partial_link复数定位find_elements_by_partial_link_text(self, link_text)
- xpath复数定位find_elements_by_xpath(self, xpath)
- css复数定位find_elements_by_css_selector(self, css_selector
这两种就是快失传了的
- find_element(self, by=’id’, value=None)
- find_elements(self, by=’id’, value=None)