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" />([\d\D]*?)'
#再次匹配数据的正则
key = re.findall('([\d\D]*?) ',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" />([\d\D]*?)'
root = re.findall(root_pattren, resp)
list_ip = []
# 再次匹配数据的正则
for i in range(len(root)):
key = re.findall('([\d\D]*?) ', 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
.........