博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
爬虫之聚焦爬虫与验证码处理
阅读量:7094 次
发布时间:2019-06-28

本文共 7169 字,大约阅读时间需要 23 分钟。

一 . 我们先安装一个叫Anaconda的软件

  参考链接:   这里我们主要用到的是jupyter notebook,下载anaconda的原因是帮助解决jupyter的依赖关系

    然后在文件夹下按住shift+右键 ->在此处打开命令窗口,输入jupyter notebook就可以了!

二 . 实现聚焦爬虫(数据解析)

  编码流程:

1.指定url2.发起请求3.获取相应数据4.数据解析5.持久化存储

  如何实现数据解析:

1.正则,(基本上不会用,这里不做介绍)2.bs43.xpath

  数据解析的原理

1.实现标签定位2.将标签中存储的文本内容或者相关的属性值进行提取

  bs4数据解析

# 环境安装    1.pip install bs4    2.pip install lxml# 使用方式:可以将一个html文档,转化为BeautifulSoup对象,然后通过对象的方法或者属性去查找指定的节点内容        (1)转化本地文件:             - soup = BeautifulSoup(open('本地文件'), 'lxml')        (2)转化网络文件:            page_text = requests.get(url, headers=headers).text            soup = BeautifulSoup(page_text , 'lxml')        (3)打印soup对象显示内容为html文件中的内容    # 调用该对象中相关的属性或者方法进行标签的定位和内容的提取    (1)根据标签名查找        - soup.a   只能找到第一个符合要求的标签    (2)获取属性        - soup.a.attrs  获取a所有的属性和属性值,返回一个字典        - soup.a.attrs['href']   获取href属性        - soup.a['href']   也可简写为这种形式    (3)获取内容        - soup.a.string        - soup.a.text        - soup.a.get_text()       【注意】如果标签还有标签,那么string获取到的结果为None,而其它两个,可以获取文本内容    (4)find:找到第一个符合要求的标签        - soup.find('a')  找到第一个符合要求的        - soup.find('a', title="xxx")        - soup.find('a', alt="xxx")        - soup.find('a', class_="xxx")        - soup.find('a', id="xxx")    (5)find_all:找到所有符合要求的标签        - soup.find_all('a')        - soup.find_all(['a','b']) 找到所有的a和b标签        - soup.find_all('a', limit=2)  限制前两个    (6)根据选择器选择指定的内容               select:soup.select('#feng')        - 常见的选择器:标签选择器(a)、类选择器(.)、id选择器(#)、层级选择器            - 层级选择器:                div .dudu #lala .meme .xixi  下面好多级                div > p > a > .la          只能是下面一级                div  p   div标签所有的p标签(子标签)        【注意】select选择器返回永远是列表,需要通过下标提取指定的对象

  示例: 爬取三国演义的章节与内容

from bs4 import BeautifulSoupurl = 'http://www.shicimingju.com/book/sanguoyanyi.html'headers = {    'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \     Chrome/70.0.3538.110 Safari/537.36'}page_text = requests.get(url=url, headers=headers, verify=False).text# 实例化soup对象soup = BeautifulSoup(page_text, 'lxml')# 解析出章节标题和详情页的链接li_list = soup.select('.book-mulu > ul > li')# 持久化存储f = open('./sanguo.txt', 'w', encoding='utf-8')for li in li_list:    title = li.a.string    detail_url = 'http://www.shicimingju.com' + li.a['href']    # 对详情页url发起请求,进行章节内容的解析提取    detail_page_text = requests.get(url=detail_url, headers=headers, verify=False).text    # 将详情页页面内容解析提取    detail_soup = BeautifulSoup(detail_page_text, 'lxml')    div_tag = detail_soup.find('div', class_='chapter_content')    content = div_tag.text    f.write(title + ':' + content + '\n')f.close()

  xpath解析(最常用)

  测试HTML页面

  使用姿势:

通用性比较强,不光python能用环境安装:pip install lxml导包:from lxml import etree# 解析原理:    1.实例化一个etree对象,且将解析的页面源码加载到该对象中    2.使用该对象中的xpath方法结合着xpath表达式进行标签定位和数据解析提取   - 本地文件:tree = etree.parse(文件名)                tree.xpath("xpath表达式")      page_text = requests.get(url, headers=headers).text  - 网络数据:tree = etree.HTML(page_text)                tree.xpath("xpath表达式")# xpath表达式/:从跟标签开始实现层级定位  /html/body/div//:从任意位置实现标签定位属性定位:    #找到class属性值为song的div标签    //div[@class="song"] 层级&索引定位:    #找到class属性值为tang的div的直系子标签ul下的第二个子标签li下的直系子标签a    //div[@class="tang"]/ul/li[2]/a逻辑运算:    #找到href属性值为空且class属性值为du的a标签    //a[@href="" and @class="du"]模糊匹配:    //div[contains(@class, "ng")]    //div[starts-with(@class, "ta")]取文本:    # /表示获取某个标签下的文本内容    # //表示获取某个标签下的文本内容和所有子标签下的文本内容    //div[@class="song"]/p[1]/text()  # 获取第一个p标签的文本    //div[@class="tang"]//text()  # 获取div下面的所有文本内容取属性:    //div[@class="tang"]//li[2]/a/@href

  示例1:

import requestsfrom lxml import etreeurl = 'http://pic.netbian.com/4kdongwu/'headers = {    'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \     Chrome/70.0.3538.110 Safari/537.36'}response = requests.get(url=url,headers=headers)# 手动设置相应数据的编码# response.encoding = 'utf-8'page_text = response.texttree = etree.HTML(page_text)li_list = tree.xpath('//div[@class="slist"]/ul/li')for li in li_list:    img_src = li.xpath('./a/img/@src')[0]    img_name = li.xpath('./a/b/text()')[0]    img_name = img_name.encode('iso-8859-1').decode('gbk')  # 解决中文乱码问题    print(img_src,img_name)

  示例2:

# 爬高清壁纸图片:http://pic.netbian.com/4kmeinv/import requestsfrom lxml import etreeimport timeurl = 'http://pic.netbian.com/4kmeinv/'headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \   Chrome/70.0.3538.110 Safari/537.36',}#获取页面文本数据response = requests.get(url=url,headers=headers)page_text = response.text#解析页面数据(获取页面中的图片链接)#创建etree对象tree = etree.HTML(page_text)li_list = tree.xpath('//div[@class="slist"]//li')#解析获取图片地址和图片的名称for li in li_list:    time.sleep(0.2) # 防止频率太频繁    image_url = li.xpath('.//img/@src')    image_url_all = 'http://pic.netbian.com'+ image_url[0]    image_name = li.xpath('.//b/text()')[0]    image_name = image_name.encode('iso-8859-1').decode('gbk')     url_name = image_url_all + ' :' + image_name        print(url_name)

 

三 . 验证码处理

  引入:

相关的门户网站在进行登录的时候,如果用户连续登录的次数超过3次或者5次的时候,就会在登录页中动态生成验证码。通过验证码达到分流和反爬的效果。

  解决办法:

使用云打码平台识别验证码

  云打码平台处理验证码的实现流程:

- 1.对携带验证码的页面数据进行抓取- 2.可以将页面数据中验证码进行解析,验证码图片下载到本地- 3.可以将验证码图片提交给三方平台进行识别,返回验证码图片上的数据值    - 云打码平台:        - 1.在官网中进行注册(普通用户和开发者用户)        - 2.登录开发者用户:            - 1.实例代码的下载(开发文档-》调用实例及最新的DLL->PythonHTTP实例下载)            - 2.创建一个软件:我的软件->添加新的软件        -3.使用示例代码中的源码文件中的代码进行修改,让其识别验证码图片中的数据值

  代码展示:

# 该函数就调用了打码平台的相关的接口对指定的验证码图片进行识别,返回图片上的数据值def getCode(codeImg):    # 云打码平台普通用户的用户名    username    = 'attila666'    # 云打码平台普通用户的密码    password    = 'attila666'                                    # 软件ID,开发者分成必要参数。登录开发者后台【我的软件】获得!    appid       = 6003                                         # 软件密钥,开发者分成必要参数。登录开发者后台【我的软件】获得!    appkey      = '1f4b564483ae5c907a1d34f8e2f2776c'        # 验证码图片文件    filename    = codeImg                            # 验证码类型,# 例:1004表示4位字母数字,不同类型收费不同。请准确填写,否则影响识别率。在此查询所有类型 http://www.yundama.com/price.html    codetype    = 3000    # 超时时间,秒    timeout     = 20                                        # 检查    if (username == 'username'):        print('请设置好相关参数再测试')    else:        # 初始化        yundama = YDMHttp(username, password, appid, appkey)        # 登陆云打码        uid = yundama.login();        print('uid: %s' % uid)        # 查询余额        balance = yundama.balance();        print('balance: %s' % balance)        # 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果        cid, result = yundama.decode(filename, codetype, timeout);        print('cid: %s, result: %s' % (cid, result))                return result

 

转载于:https://www.cnblogs.com/attila/p/10853886.html

你可能感兴趣的文章
java多态性,父类引用指向子类对象
查看>>
机器学习入门03 - 降低损失 (Reducing Loss)
查看>>
Material Design(七)--Snackbar
查看>>
文件MD5
查看>>
收集的博客网址springboot、cloud
查看>>
解析函數論 Page 29 命題(3) 模的下界的可達性
查看>>
windows异常调用顺序
查看>>
红黑树
查看>>
Sass
查看>>
Objective-C中Block语法、Block使用以及通过Block实现数组排序
查看>>
[转载]从业务运维转到产品经理,我摸爬滚打的产品之路
查看>>
比较正在使用的域名 和顶层窗口的域名
查看>>
Gitlab - Mac本机访问VirtualBox上搭建的Gitlab
查看>>
Bootstrap的Model源码详细注释 (转)
查看>>
java采用jxl写入一个Excel文件
查看>>
1171:大整数的因子
查看>>
传说中的数据结构 栈
查看>>
结对-结对编项目作业名称-设计文档
查看>>
Cesium 获取当前视图范围
查看>>
javascript基础
查看>>