尝试B站登入,遇到的问题大致如下。
学习的是崔庆才编写的《python3网络爬虫开发实战》
1.EC显示等待模块中需要加括号
2.for循环的列表形式
3.报错:'click_image' object has no attribute 'wait'
4.报错:chromedriver' executable needs to be in PATH
5.报错:presence_of_element_located() takes 1 positional argument but 2 were given
6.报错:int() argument must be a string, a bytes-like object or a number, not 'list'
7.selenium截图出现偏差
8.crop()函数裁剪错误
9.BytesIO()的用法
10.file.getvalue()的用法
(一)1.EC显示等待模块中需要加括号
EC显示模块,看代码
def login_in(self):
self.browser.get(self.url)
self.browser.maximize_window()
username = self.wait.until(EC.presence_of_element_located((By.ID, 'login-username' )))
password = self.wait.until(EC.presence_of_element_located((By.ID, 'login-passwd' )))
button = self.wait.until(EC.element_to_be_clickable((By.LINK_TEXT,'登录')))
username.send_keys(bilibili_username)
password.send_keys(bilibili_password)
button.click()
time.sleep(2)
注意EC.presence_of_element_located()这个函数里面的是需要写成
EC.presence_of_element_located((By.ID, 'login-username'))里面需要有一个括号
(二)2.for循环的列表形式
for循环有两种方式,这次遇到的写法是这样子的
def get_points(self,captch_result):
'''
:param captch_result: 超级鹰输出的
:return:
'''
groups = captch_result.get('pic_str').split('|')
locations = [[int(number) for number in group.split(',')] for group in groups]
return locations
其中int(number)是输出的内容,
for number in group.split(',') 是内层循环
for group in groups 是外层循环
不过输出的内容是啥样的我还不是很清楚,待续。
(三)报错:'click_image' object has no attribute 'wait'
? ? ? ? EC显示等待
class click_image():
def first_login(self):
self.url = 'https://passport.bilibili.com/login'
self.browser = webdriver.Chrome()
self.wait = WebDriverWait(self.browser,20)
self.chaojiying = Chaojiying(chaojiying_username,chaojiying_password,chaojiying_soft_id)
一开始是这样子的,后来一直给我报错,我将代码更改为
class click_image():
def __init__(self):
self.url = 'https://passport.bilibili.com/login'
self.browser = webdriver.Chrome()
self.wait = WebDriverWait(self.browser,20)
self.chaojiying = Chaojiying(chaojiying_username,chaojiying_password,chaojiying_soft_id)
将函数名称换成了__init__(self):就可以了
(四)chromedriver' executable needs to be in PATH
这个只需要将chromedriver.exe 分别放入 含有chrome.exe 和python37的文件夹里,再将chromedriver.exe放入环境变量的系统PATH中即可,如下
?之后再右键我的电脑-属性-高级系统设置-环境变量-双击系统变量中的path-新建,将
上图中的地址:C:\Users\15466\AppData\Local\Google\Chrome\Application
放入之后,一路确定即可。
(五)presence_of_element_located() takes 1 positional argument but 2 were given
?解决方法就是第一个里面提到的
(六)int() argument must be a string, a bytes-like object or a number, not 'list'
def touch_click(self,locations):
for location in locations:
print(location)
ActionChains(self.browser).move_to_element_with_offset(self.get_image(),location[0],
location[1]).click().perform()
time.sleep(1)
↑↑↑这个是正确的。
当时我报错的原因是在:
ActionChains(self.browser).move_to_element_with_offset(self.get_image(),locations[0],
locations[1]).click().perform()
是的,仔细看就会发现我在location的后面加了一个s
(七)selenium截图出现偏差
1.电脑系统的缩放比例
我这里是125%?,所以只需要改成100%,然后重启电脑就可以
2.在后续的坐标乘以1.25(如下)
def crop_screenshot(self,name='captch.png'):
top,bottom,left,right= self.get_image_location()
screenshot = self.get_screenshot()
captch = screenshot.crop((left*1.25,top*1.25,right*1.25,bottom*1.25))
captch.save(name)
return captch
3.还有一个,反正我懒得看了
(八)crop()函数裁剪错误
def crop_screenshot(self,name='captch.png'):
top,bottom,left,right= self.get_image_location()
screenshot = self.get_screenshot()
captch = screenshot.crop((left,top,right,bottom))
captch.save(name)
return captch
crop(x,y,x+width,y+height)
但是一开始脑抽写的是
captch = screenshot.crop((top,bottom,left,right))
可把孩子愁坏了。
(九)BytesIO()的用法
BytesIO实现了在内存中读写bytes
可以
file = BytesIO()
来创建一个文件夹
(十)file.getvalue()的用法
有人解释下吗,我不理解。。。
附上代码:
from PIL import Image
from pach.chaojiying_Python.chaojiying import Chaojiying
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import ActionChains
import time
from io import BytesIO
'''准备工作'''
chaojiying_username = '超级鹰用户名'
chaojiying_password = '超级鹰密码'
chaojiying_soft_id = '软件ID'
chaojiying_kind = '验证码类型'
bilibili_username = 'B站账号'
bilibili_password = 'B站密码'
class click_image():
def __init__(self):
self.url = 'https://passport.bilibili.com/login'
self.browser = webdriver.Chrome()
self.wait = WebDriverWait(self.browser,20)
self.chaojiying = Chaojiying(chaojiying_username,chaojiying_password,chaojiying_soft_id)
def login_in(self):
self.browser.get(self.url)
self.browser.maximize_window()
username = self.wait.until(EC.presence_of_element_located((By.ID, 'login-username' )))
password = self.wait.until(EC.presence_of_element_located((By.ID, 'login-passwd' )))
button = self.wait.until(EC.element_to_be_clickable((By.LINK_TEXT,'登录')))
username.send_keys(bilibili_username)
password.send_keys(bilibili_password)
button.click()
time.sleep(2)
def close(self):
self.browser.close()
def get_image(self):
images = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME,'geetest_item_img')))
return images
def get_image_location(self):
images = self.get_image()
location = images.location
size = images.size
top,bottomm,left,right = location['y'],location['y']+size['height'],location['x'],location['x']+size['width']
return (top,bottomm,left,right)
def get_screenshot(self):
screenshot = self.browser.get_screenshot_as_png()
screenshot = Image.open(BytesIO(screenshot))
return screenshot
def crop_screenshot(self,name='captch.png'):
top,bottom,left,right= self.get_image_location()
screenshot = self.get_screenshot()
captch = screenshot.crop((left,top,right,bottom))
captch.save(name)
return captch
def get_points(self,captch_result):
'''
:param captch_result: 超级鹰输出的
:return:
'''
groups = captch_result.get('pic_str').split('|')
locations = [[int(number) for number in group.split(',')] for group in groups]
return locations
def touch_click(self,locations):
for location in locations:
print(location)
ActionChains(self.browser).move_to_element_with_offset(self.get_image(),location[0],
location[1]).click().perform()
time.sleep(1)
def login_click(self):
button = self.wait.until(EC.element_to_be_clickable((By.LINK_TEXT,'确认')))
button.click()
def bilibili_login(self):
self.login_in()
captch = self.crop_screenshot()
file = BytesIO()
captch.save(file , format='PNG' )
result = self.chaojiying.post_pic(file.getvalue(),chaojiying_kind)
print(result)
locations = self.get_points(result)
self.touch_click(locations)
self.login_click()
if __name__ == '__main__':
login = click_image()
login.bilibili_login()
|