文章目录
- 一、抽屉半自动点赞
- 二、xpath的使用
- 三、动作链
- 四、打码平台
- 介绍
- 超级鹰打码基本测试
- 五、自动登录超级鹰
- 六、scrapy框架
- 介绍
- 安装
- 创建爬虫项目
一、抽屉半自动点赞
'登录抽屉账号保存cookies'
import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
bro = webdriver.Chrome()
bro.get('https://dig.chouti.com/')
bro.implicitly_wait(10)
bro.maximize_window()
# 找到登录按钮,点击
submit_btn = bro.find_element(by=By.ID,value='login_btn')
submit_btn.click()
# 找到用户名密码框--输入用户名和密码
username = bro.find_element(By.CSS_SELECTOR,'body > div.login-dialog.dialog.animated2.scaleIn > div > div.login-body > div.form-item.login-item.clearfix.phone-item.mt24 > div.input-item.input-item-short.left.clearfix > input')
password = bro.find_element(By.CSS_SELECTOR,'body > div.login-dialog.dialog.animated2.scaleIn > div > div.login-footer > div.form-item.login-item.clearfix.mt24 > div > input.input.pwd-input.pwd-input-active.pwd-password-input')
username.send_keys('xxxxx') # 手机号
time.sleep(2)
password.send_keys('xxxx') # 密码
time.sleep(2)
submit = bro.find_element(By.CSS_SELECTOR,'body > div.login-dialog.dialog.animated2.scaleIn > div > div.login-footer > div:nth-child(4) > button')
submit.click()
input('等待人工确认登录----回车键后登录')
# 登陆成功保存cookie
cookies = bro.get_cookies()
print(cookies)
with open('chouti.json','wt',encoding='utf-8')as f:
json.dump(cookies,f)
time.sleep(5)
bro.close()
'使用上面保存的cookie进行登录并点赞'
# 使用requests模块点赞,把当前页面所有的文章点一遍
import requests
from bs4 import BeautifulSoup
import json
# 1.获取第一个的所有文章的id号
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
'Referer':'https://dig.chouti.com/'
}
res = requests.get('https://dig.chouti.com/',headers=headers)
# print(res.text)
# 解析
soup=BeautifulSoup(res.text,'lxml')
div_list = soup.find_all(name='div',class_='link-item')
# 获取本地cookie
with open('chouti.json','rt',encoding='utf-8')as f:
cookies = json.load(f)
requests_cookies={}
for cookie in cookies:
requests_cookies[cookie['name']]=cookie['value']
print('requests模块需要的cookie格式',requests_cookies)
for div in div_list:
article_id = div.attrs.get('data-id')
# print(article_id)
# 要携带cookie
data = {'linkId':article_id}
res = requests.post('https://dig.chouti.com/link/vote',headers=headers,cookies=requests_cookies,data=data)
print(res.text)
二、xpath的使用
'''
# 语法格式如下(记住这几个)
1 标签名 # 找xml中所有这个标签
2 / # 只找一层]
3 // # 子子孙孙都会找
4 . # 从当前路径下
5 .. # 上一层
6 @属性名 # 找有这个属性的标签
'''
doc='''
<html>
<head>
<base href='http://example.com/' />
<title>Example website</title>
</head>
<body>
<div id='images'>
<a href='image1.html' id='id_a' name='lqz'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>
<a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>
<a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>
<a href='image4.html' class='li'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>
<a href='image5.html' class='li li-item' name='items'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>
<a href='image6.html' name='items'><span><h5>test</h5></span>Name: My image 6 <br /><img src='image6_thumb.jpg' /></a>
</div>
</body>
</html>
'''
from lxml import etree
html=etree.HTML(doc) # 加载字符串
# html=etree.parse('search.html',etree.HTMLParser()) # 加载文件
# 1 所有节点
print(html.xpath('//*'))
print(html.xpath('/*'))
# 2 指定节点(结果为列表)
print(html.xpath('//head'))
# 3 子节点,子孙节点
print(html.xpath('//div/a'))
print(html.xpath('//body/a')) #无数据
print(html.xpath('//body//a'))
# 4 父节点
print(html.xpath('//body//a[@href="image1.html"]/..')) # 上一节点 div a..
print(html.xpath('//body//a[1]/..')) # 从1开始 第一个a标签..
# 也可以这样
print(html.xpath('//body//a[1]/parent::*')) # 找父亲---》父亲可以是任意标签
print(html.xpath('//body//a[1]/parent::div')) # 找父亲---》父亲可以是任意标签
# 5 属性匹配
print(html.xpath('//a[@href="image1.html"]')) # 属性匹配 标签为 a
# 6 文本获取(记住)
print(html.xpath('//body//a[@href="image1.html"]/text()')) # 内容获取 a标签内的内容['Name: My image 1 ']
# 7 属性获取(记住)
print(html.xpath('//body//a/@href')) # 拿所有a的href属性
print(html.xpath('//body//a[1]/@href')) # 从1开始
# 注意从1 开始取(不是从0)
print(html.xpath('//body//a[1]/@href'))
# 8 属性多值匹配
# a 标签有多个class类,直接匹配就不可以了,需要用contains
print(html.xpath('//body//a[@class="li"]')) # 有个类叫li的所有a标签,因为这个a有俩类
print(html.xpath('//body//a[contains(@class,"li")]')) # 属性多值匹配 匹配a标签内有class = li的标签
print(html.xpath('//body//a[contains(@class,"li")]/text()')) # 属性多值匹配 匹配a标签内有class = li的标签的值
# 9 多属性匹配
print(html.xpath('//body//a[contains(@class,"li") or @name="items"]')) # 多属性匹配 匹配a标签内有class=li or name=itmes的内容
print(html.xpath('//body//a[contains(@class,"li") and @name="items"]/text()')) # 多属性匹配 匹配a标签内有class=li and name=itmes的内容
print(html.xpath('//body//a[contains(@class,"li")]/text()'))
# 10 按序选择
print(html.xpath('//a[2]/text()')) # 按序选择 查找第二个a标签的内容
print(html.xpath('//a[2]/@href')) # 按序选择 查找第三个a标签的@href内容
# 取最后一个
print(html.xpath('//a[last()]/@href')) # 按序选择 查找最后一个a标签的@href内容
# 位置小于3的
print(html.xpath('//a[position()<3]/@href')) # 按序选择 查找标签位置小于3的位置
# 倒数第二个
print(html.xpath('//a[last()-2]/@href')) # 按序选择 查找倒数第二个a标签
# 11 节点轴选择
# ancestor:祖先节点
# 使用了* 获取所有祖先节点
print(html.xpath('//a/ancestor::*'))
# # 获取祖先节点中的div
print(html.xpath('//a/ancestor::html'))
# attribute:属性值
print(html.xpath('//a[1]/attribute::*')) # 获取第一个a标签的属性值
print(html.xpath('//a[1]/attribute::id'))
# child:直接子节点
print(html.xpath('//a[1]/child::*')) # 获取第一个a标签的的子节点
print(html.xpath('//a[1]/child::img'))
# descendant:所有子孙节点
print(html.xpath('//a[6]/descendant::*')) # 获取第六个a标签的子节点
# following:当前节点之后所有节点
print(html.xpath('//a[1]/following::*')) # 获取第一个a标签之后的所有节点
print(html.xpath('//a[1]/following::*[1]/@href')) # 获取第1个a标签之后的所有节点里面的第一个href里面所有的节点
# following-sibling:当前节点之后同级节点
print(html.xpath('//a[1]/following-sibling::*')) # 获取第一个a标签之后所有同级节点
print(html.xpath('//a[1]/following-sibling::a')) # 获取第一个a标签之后同级a节点
print(html.xpath('//a[1]/following-sibling::*[2]')) # 获取第一个a标签之后所有同级节点第二个节点
print(html.xpath('//a[1]/following-sibling::*[2]/@href')) # 获取第一个a标签之后所有同级节点第二个节点里面href的属性
三、动作链
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait # 等待页面加载某些元素
import time
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
driver.implicitly_wait(3)
driver.maximize_window()
try:
driver.switch_to.frame('iframeResult') ##切换到iframeResult
sourse = driver.find_element(By.ID, 'draggable')
target = driver.find_element(By.ID, 'droppable')
'''拿到actions对象后,对象有很多方法
1 把标签1 拖动到标签2上
actions.drag_and_drop(标签1,标签2)
2 一点点滑动某个标签
actions.click_and_hold(标签1).perform()
actions.move_by_offset(x,y) # 把标签1 滑动x轴和y轴的距离
3 滑动某个标签,一些距离
actions.drag_and_drop_by_offset(标签1,x,y)
'''
# 方式一:基于同一个动作链串行执行
# actions = ActionChains(driver) # 拿到动作链对象
# actions.drag_and_drop(sourse, target) # 把动作放到动作链中,准备串行执行
# actions.perform()
# 方式二:不同的动作链,每次移动的位移都不同
ActionChains(driver).click_and_hold(sourse).perform() # 鼠标点中源 标签 不松开
distance=target.location['x']-sourse.location['x']
track = 0
while track < distance:
ActionChains(driver).move_by_offset(xoffset=10, yoffset=0).perform()
track += 10
ActionChains(driver).release().perform()
# 方式三:
# actions = ActionChains(driver)
# actions.drag_and_drop_by_offset(sourse,200,0).perform()
time.sleep(5)
finally:
driver.close()
四、打码平台
介绍
'网站有验证码,验证码破解'
-简单验证码:字母数字组合---》免费的就能破---》ddddocr
-https://www.jb51.net/article/249636.htm
-复杂的:收费---》打码平台--》花钱帮我们破解验证码
把验证码图片传给它--->它识别完--》返回结果---》根据复杂度收费
-超级鹰:http://www.chaojiying.com/-下载SDK
-云打码:https://zhuce.jfbym.com/price/
超级鹰打码基本测试
#!/usr/bin/env python
# coding:utf-8
import requests
from hashlib import md5
class Chaojiying_Client(object):
def __init__(self, username, password, soft_id):
self.username = username
password = password.encode('utf8')
self.password = md5(password).hexdigest()
self.soft_id = soft_id
self.base_params = {
'user': self.username,
'pass2': self.password,
'softid': self.soft_id,
}
self.headers = {
'Connection': 'Keep-Alive',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
}
def PostPic(self, im, codetype):
"""
im: 图片字节
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
}
params.update(self.base_params)
files = {'userfile': ('ccc.jpg', im)}
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
return r.json()
def PostPic_base64(self, base64_str, codetype):
"""
im: 图片字节
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
'file_base64':base64_str
}
params.update(self.base_params)
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, headers=self.headers)
return r.json()
def ReportError(self, im_id):
"""
im_id:报错题目的图片ID
"""
params = {
'id': im_id,
}
params.update(self.base_params)
r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
return r.json()
if __name__ == '__main__':
# chaojiying = Chaojiying_Client('超级鹰用户名', '超级鹰用户名的密码', '96001') #用户中心>>软件ID 生成一个替换 96001
im = open('a.jpg', 'rb').read() #本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
print(chaojiying.PostPic(im, 1902)) #1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
#print chaojiying.PostPic(base64_str, 1902) #此处为传入 base64代码
五、自动登录超级鹰
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from PIL import Image
from chaojiying import Chaojiying_Client
bro = webdriver.Chrome()
bro.get('https://www.chaojiying.com/user/login/')
bro.implicitly_wait(10)
bro.maximize_window()
# 截图全屏
bro.save_screenshot('main.png')
# 找到用户名和密码,验证码输入框
username = bro.find_element(By.CSS_SELECTOR,'body > div.wrapper_danye > div > div.content_login > div.login_form > form > p.login_form_item > input')
password = bro.find_element(By.CSS_SELECTOR,'body > div.wrapper_danye > div > div.content_login > div.login_form > form > p:nth-child(2) > input')
code = bro.find_element(By.XPATH,'/html/body/div[3]/div/div[3]/div[1]/form/p[3]/input')
# 输入用户名,密码,验证码
username.send_keys('')
time.sleep(2)
password.send_keys('!')
time.sleep(2)
# 破解验证码,从截图中获取验证码
img=bro.find_element(By.XPATH,'/html/body/div[3]/div/div[3]/div[1]/form/div/img')
# 找到img的大小和位置
location = img.location
size = img.size
print('大小是:', img.size)
print('位置是:', img.location)
# 获取图的 起始位置坐标 结束位置坐标
img_tu = (int(location['x']), int(location['y']), int(location['x'] + size['width']), int(location['y'] + size['height']))
# 使用pillow,根据坐标,扣除验证码图片
img = Image.open('./main.png')
# 抠图
fram = img.crop(img_tu)
# 截出来的小图
fram.save('code1.png')
# 调用超级鹰
# chaojiying = Chaojiying_Client('17786176326','Mao0227!','958083')
# im = open('code1.png', 'rb').read() #本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
# real_code = chaojiying.PostPic(im, 1902)['pic_str'] #1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
# 使用ddddocr
import ddddocr
ocr = ddddocr.DdddOcr(old=True,show_ad=False)
# 第一个验证码截图保存:verification_code_1.png
with open('./code1.png','rb')as f:
image = f.read()
real_code = ocr.classification(image)
code.send_keys(real_code)
time.sleep(5)
# 找到登录按钮,登录
submit = bro.find_element(By.XPATH,'/html/body/div[3]/div/div[3]/div[1]/form/p[4]/input')
submit.click()
time.sleep(10)
bro.close()
六、scrapy框架
介绍
前面讲的都是使用模块 做专业的爬虫可以使用框架Scrapy爬虫框架(做爬虫用的东西都封装好了只需要在固定的位置写固定的代码即可)
Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速、简单、可扩展的方式从网站中提取所需的数据。但目前Scrapy的用途十分广泛,可用于如数据挖掘、监测和自动化测试等领域,也可以应用在获取API所返回的数据或者通用的网络爬虫
安装
'安装 (win看人品,linux,mac一点问题没有)'
-pip install scrapy
-装不上,基本上是因为twisted装不了,单独装
1、pip3 install wheel #安装后,便支持通过wheel文件安装软件,wheel文件官网:https://www.lfd.uci.edu/~gohlke/pythonlibs
3、pip3 install lxml
4、pip3 install pyopenssl
5、下载并安装pywin32:https://sourceforge.net/projects/pywin32/files/pywin32/
6、下载twisted的wheel文件:http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
7、执行pip3 install 下载目录\Twisted-17.9.0-cp36-cp36m-win_amd64.whl
8、pip3 install scrapy
在 D:\Python解释器对应的版本\Scripts 路径下 会有scrapy可执行文件
-它等同于,你安装了django--》多两个djagno-admin可执行文件
创建爬虫项目
1.创建项目
scrapy startproject 爬虫名称
2.创建爬虫
scrapy genspider cnblogs www.cnblogs.com # 这里是创建一个cnblogs的爬虫
3.scrapy crawl cnblogs --nolog # --log 取消日志功能
4.pycharm中运行新建run.py
from scrapy.cmdline import execute
execute(['scrapy', 'crawl', 'cnblogs','--nolog'])