• 爬虫入门四(抽屉半自动点赞、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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    	'使用上面保存的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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    二、xpath的使用

    '''
    # 语法格式如下(记住这几个)
    1 标签名   # 找xml中所有这个标签
    2 /       # 只找一层]
    3 //      # 子子孙孙都会找
    4 .       # 从当前路径下
    5 ..      # 上一层
    6 @属性名 # 找有这个属性的标签
    '''
    
    doc='''
    
     
      
      Example website
     
     
      
     
    
    '''
    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的属性
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113

    三、动作链

    	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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    四、打码平台

    介绍

    	'网站有验证码,验证码破解'
    	-简单验证码:字母数字组合---》免费的就能破---》ddddocr
        -https://www.jb51.net/article/249636.htm
        
        -复杂的:收费---》打码平台--》花钱帮我们破解验证码
        	把验证码图片传给它--->它识别完--》返回结果---》根据复杂度收费
    		-超级鹰:http://www.chaojiying.com/-下载SDK
            -云打码:https://zhuce.jfbym.com/price/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    超级鹰打码基本测试

    #!/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代码
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    五、自动登录超级鹰

    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    六、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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    创建爬虫项目

    	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'])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    maven-resources-production:trunk-auth: java.lang.NegativeArraySizeException
    基于springboot实现基于Java的超市进销存系统项目【项目源码+论文说明】
    从0到1学SpringCloud——13 gateway RouteLocator配置路由规则
    three.js学习-智慧城市
    从位图到布隆过滤器,C#实现
    pytorch中.size()、.item、argmax()、.cpu()、.detach()和.data的使用
    【算法】万圣节前夕的迷宫挑战(二)
    桃花灿烂
    将 .NET Aspire 部署到 Kubernetes 集群
    JAVASE 第十六天
  • 原文地址:https://blog.csdn.net/achen_m/article/details/136283509