Task3(2天) 3.1 安装selenium并学习 1. 安装selenium并学习。 2. 使用selenium模拟登陆163邮箱。 3. 163邮箱直通点:https://mail.163.com/ 。 4. 参考资料:https://blog.csdn.net/weixin_42937385/article/details/88150379 3.2 学习IP相关知识 1. 学习什么是IP,为什么会出现IP被封,如何应对IP被封的问题。 2. 抓取西刺代理,并构建自己的代理池。 3. 西刺直通点:https://www.xicidaili.com/ 。 4. 参考资料:https://blog.csdn.net/weixin_43720396/article/details/88218204
Selenium是一个用于测试网站的自动化测试工具,支持各种浏览器包括Chrome、Firefox、Safari等主流界面浏览器,同时也支持phantomJS无界面浏览器。并且支持多种操作系统:如Windows、Linux、IOS、Android等。
详细教程可见:Selenium官网教程
对于python库的安装,一般有两种方式:
pip install selenium
,即可完成selenium安装。Selenium3.x调用浏览器必须有一个webdriver驱动文件。当Selenium升级到3.0之后,对不同的浏览器驱动进行了规范。如果想使用selenium驱动不同的浏览器,必须单独下载并设置不同的浏览器驱动。
因为我用的是Chrome浏览器,所以这里只提供Chrome驱动文件下载(根据自己的浏览器版本对应选择就好):点击下载chromedrive
我的Chrome浏览器版本(在浏览器的帮助选项中可查得)为:70.0.3538.110(正式版本) (32 位),其对应的chromedrive为:chromedrive 密码:5paf
设置浏览器的地址非常简单。我们将解压后的chromedriver.exe
文件放到Chrome的安装文件中,Chrome的安装路径可以通过右击桌面的Chrome,点击属性就可以查到。放好后将该路径添加到环境变量中。
我的电脑–>属性–>高级系统设置–>环境变量–>系统变量–>Path,将上述路径目录添加到Path的值中。
验证浏览器驱动是否正常使用:
from selenium import webdriver driver = webdriver.Chrome() # Chrome浏览器
如果正常使用的话,就会弹出chrome的窗口,并显示chrome正受到自动测试软件的控制。
Selenium提供了8种定位方式。
定位方式 | 在Python selenium中所对应的方法 | 含义 |
---|---|---|
id | find_element_by_id() | 通过id定位 |
name | find_element_by_name() | 通过name定位 |
class name | find_element_by_class_name() | 通过类名进行定位 |
tag name | find_element_by_tag_name() | 通过标签定位 |
link text | find_element_by_link_text() | 通过完整超链接定位 |
partial link text | find_element_by_partial_link_text() | 通过部分链接定位 |
xpath | find_element_by_xpath() | 通过xpath定位 |
css selector | find_element_by_css_selector() | 通过css选择器进行定位 |
要求:使用selenium模拟登陆163邮箱
from selenium import webdriver import time #打开浏览器 driver = webdriver.Chrome() #设置地址 url = "https://mail.163.com/" #访问网址 driver.get(url)
定位登录框
frame标签有frameset、frame、iframe三种,frameset跟其他普通标签没有区别,不会影响到正常的定位。而frame与iframe对selenium定位而言是一样的,内部的元素都会不能直接定位到。
Web应用中经常会遇到frame/iframe 表单嵌套页面的应用,WebDriver 只能在一个页面上对元素识别与定位,对于frame/iframe 表单内嵌页面上的元素无法直接定位。这时就需要通过switch_to.frame()
方法将当前定位的主体切换为frame/iframe 表单的内嵌页面中。
而且加载这个iframe需要一定时间,所以需要设一个等待直至获取到标签
time.sleep(1) #设置等待直至获取标签 driver.switch_to.frame(0) #找到邮箱账号登录框对应的iframe,由于网页中iframe的id是动态的,所以不能用id寻找。用frame的index来定位,定位第一个frame(index下标从0开始)。
name=driver.find_element_by_name('email')#找到邮箱账号输入框 name.send_keys("输入自己的163邮箱账号")#将自己的邮箱地址输入到邮箱账号框中
name=driver.find_element_by_name('password')#找到密码输入框 name.send_keys("输入自己的邮箱密码")#输入自己的邮箱密码
login = driver.find_element_by_id('dologin')#找到登陆按钮 login.click() #点击登录按钮
全部代码如下:
from selenium import webdriver import time #打开浏览器 driver = webdriver.Chrome() #设置地址 url = "https://mail.163.com/" #访问网址 driver.get(url) time.sleep(1) driver.switch_to.frame(0)#找到邮箱账号登录框对应的iframe,由于网页中iframe的id是动态的,所以不能用id寻找 name = driver.find_element_by_name('email')#找到邮箱账号输入框 name.send_keys('163邮箱账号')#将自己的邮箱地址输入到邮箱账号框中 time.sleep(1) name = driver.find_element_by_name('password')#找到密码输入框 name.send_keys('163邮箱密码')#输入自己的邮箱密码 login = driver.find_element_by_id('dologin')#找到登陆按钮 login.click()#点击登陆按钮
成功登录页面如下:
比如: time.sleep(random.randint(0,3)) # 暂停0~3秒的整数秒,时间区间:[0,3] 或: time.sleep(random.random()) # 暂停0~1秒,时间区间:[0,1)
cookies = dict(uuid='b18f0e70-8705-470d-bc4b-09a8da617e15',UM_distinctid='15d188be71d50-013c49b12ec14a-3f73035d-100200-15d188be71ffd') resp = requests.get(url,cookies = cookies) # 把浏览器的cookies字符串转成字典 def cookies2dict(cookies): items = cookies.split(';') d = {} for item in items: kv = item.split('=',1) k = kv[0] v = kv[1] d[k] = v return d
注意: 用浏览器cookies发起请求后,如果请求频率过于频繁仍会被封IP,这时可以在浏览器上进行相应的手工验证(比如点击验证图片等),然后就可以继续正常使用该cookies发起请求。
4. 使用代理
可以换着用多个代理IP来进行访问,防止同一个IP发起过多请求而被封IP,比如:
proxies = {'http':'http://10.10.10.10:8765','https':'https://10.10.10.10:8765'} resp = requests.get(url,proxies = proxies) # 注:免费的代理IP可以在这个网站上获取:http://www.xicidaili.com/nn/
要求:西刺直通点:西刺免费代理IP
#匹配整体数据的正则 root_pattren = 'alt="Cn" /></td>([\d\D]*?)</tr>' #再次匹配数据的正则 key = re.findall('<td>([\d\D]*?)</td>',s)
import requests import traceback import re class Downloader(object): def __init__(self): self.headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36' } def download(self, url): print('正在下载页面:{}'.format(url)) try: resp = requests.get(url, headers=self.headers) if resp.status_code == 200: return resp.text else: raise ConnectionError except Exception: print('下载页面出错:{}'.format(url)) traceback.print_exc() def get_ip_list(self, resp): try: # 匹配整体数据的正则 root_pattren = 'alt="Cn" /></td>([\d\D]*?)</tr>' root = re.findall(root_pattren, resp) list_ip = [] # 再次匹配数据的正则 for i in range(len(root)): key = re.findall('<td>([\d\D]*?)</td>', root[i]) list_ip.append(key[3].lower() + '://' + key[0] + ':' + key[1]) return list_ip except Exception: print('解析IP地址出错') traceback.print_exc() def main(): url = 'https://www.xicidaili.com/' resp = Downloader().download(url) info = Downloader().get_ip_list(resp) for i in info: print(i) if __name__ == '__main__': main()
运行结果为:
正在下载页面:https://www.xicidaili.com/ https://171.41.82.37:9999 https://171.41.82.74:9999 https://180.118.243.185:808 https://49.70.64.221:9999 http://121.61.1.67:9999 http://180.119.141.144:9999 https://125.126.222.12:9999 https://111.177.185.208:9999 https://111.177.182.20:9999 https://60.190.250.120:8080 http://112.85.164.93:9999 http://116.209.59.64:9999 .........