人工智能(crawler)—— 爬虫琐碎

版权声明:记事、留心、分享;如有侵权、违规情况等,请及时联系原创作者。 https://blog.csdn.net/qq_27297393/article/details/82251006

参考源码:https://github.com/hilqiqi0/AI/tree/master/4.crawler


HASH算法(对某段信息打指纹,能够压缩信息,HASH算法是不可逆的)

import hashlib
h = hashlib.md5()
h.update(("hello world").encode("utf-8"))
print(h.hexdigest())

User-Agent:

方法1、user-agent池

python爬虫之如何随机更换User-Agent
这是python里面的一个user-agent池,非常好用!
首先,安装fake-useragent
        pip install fake-useragent
然后,使用方法

from fake_useragent import UserAgent

ua = UserAgent()
headers = {'User-Agent':ua.random}

方法2、user-agent大全

转载:https://www.cnblogs.com/1906859953Lucas/p/9027165.html


XPath语言:可以用来提取xml,html信息的语言
在Python中是使用lxml这个库来实现的;
一个在爬虫中使用XPath的万能方法:
    在浏览器中Copy XPath;
缺点:可读性差,可维护性差;


使用BeautifulSoup,一定要记住一个方法:
findAll
比如soup.findAll('p', align="blah")
相对于XPath而言,好处是:可读性好,可维护性好;
缺点:慢;


Selenium+Chrome浏览器:
     安装Selenium:
     在anaconda prompt中:
    (base) C:\Users\Python>conda install selenium
看起来很美,从理论上来说,只要用户能访问的数据,都可以抓取到。
但是:从时间,空间,及效率上来说,这个方案都有其缺陷。
结论:
    1.如果可以使用get,post方法来获取数据,不要使用Selenium+浏览器方案;
    2.实在没有办法抓取到数据的时候再使用Selenium+浏览器的方案,
生产环境中使用headless的浏览器;
补充说明:
    由于Python的进程和浏览器的进程是两个不同的进程,所以在Python的
进程退出时,可以尝试使用browser.close()让浏览器关闭,但是不能保证
其一定关闭,这样就可能造成资源泄露。一个补救的措施就是:
在适当的时候,kill掉相关的浏览器进程(Linux命令);


RSA算法:
        RSA加密算法是一种非对称加密算法;加密算法不重要,秘钥才能保密;
秘钥:如果加解密用同一个秘钥,对称加密;
        如果加解密用两个不同的秘钥,非对称加密;    
               有两个秘钥:公钥,私钥;
                      用公钥加密的数据需要使用私钥来解;
                      用私钥加密的数据需要使用公钥来解;
                      公钥可以随便给别人,私钥不能给;
HTTPS使用非对称加密:    
        服务器  客户端浏览器;
通信的过程:服务器把数据用私钥加密,把加密之后的数据和公钥一起发给客户端;完成一次通信;客户端把要发给服务器的数据用服务器所给的公钥加密,然后传给服务器;完成一次通信,服务器可以用私钥来解密;n = p*q,当n是一个巨大的数时,理论上在有限的时间之内这个两个质数p,q是分解不出来。p,q是私钥,n是公钥;abcde,bcdef


正则表达式详解:https://www.cnblogs.com/deerchao/archive/2006/08/24/zhengzhe30fengzhongjiaocheng.html

万能的正则表达式:([\s\S])*?   

RegexTester工具:https://github.com/hilqiqi0/AI/blob/master/4.crawler/RegexTester.exe


GET:
当我们在做GET请求时,事实上需要做一次urlencode:
      https://www.baidu.com/s?wd=python%20%E7%88%AC%E8%99%AB&oq=python%2520%25E7%2588%25AC%25E8%2599%25AB
urlencode in python:
    wd = {"wd":keyword} #Python爬虫
    wd = urllib.parse.urlencode(wd) #url encode 编码
    # wd=Python%E7%88%AC%E8%99%AB


cookie,session作用?
    用户曾经访问过个这个网站,我们需要在HTTP协议之外用一些额外的信息和技术来标识这个用户曾经来过;为了让用户体验更好;所以我们的爬虫程序可以巧妙的利用这个漏洞来达到登录获取信息的效果;

参考:https://github.com/hilqiqi0/AI/blob/master/4.crawler/cookieJar.py


使用tesseract做OCR 验证码识别
安装tesseract
      sudo apt-get install tesseract-ocr
      sudo pip install pytesseract

测试:tesseract
      from pytesseract import *

参考代码:https://github.com/hilqiqi0/AI/tree/master/4.crawler/TestOCR

训练与测试参考文章:https://www.cnblogs.com/cnlian/p/5765871.html


在captchaTest.py程序中:
有一张验证码的图片:去噪音,找出验证码的色彩;
        1.背景色与前景色的区分;
        2.提取出一个个字符;
        3.使用余弦相似度来计算两个字符之间的相似度;
                    参考:数学之美之余弦定理与新闻分类:https://blog.csdn.net/whiterbear/article/details/45583883
        4.得到当前字符最大概率匹配的样本集中的字符;

参考代码:字符识别(https://github.com/hilqiqi0/AI/tree/master/4.crawler/python_captcha


打码平台运作的方式:
        1)首先在打码平台注册账号,获取到合法的Key,ID等信息;
        2)使用这些Key,ID去调对方的API:读取文件成字节流,做一次Base64转码,去调API接口,返回结果;
        3)得到结果,进行下一步操作;如果出错,根据返回结果来判断如果排错;如果使用图像识别的技术实在搞不定验证码,可以求助打码平台;
eg:http://www.fateadm.com/


在Python中如何写日志?
        使用logging写日志;
日志的级别:
        CRITICAL = 50
        FATAL = CRITICAL
        ERROR = 40
        WARNING = 30
        WARN = WARNING
        INFO = 20
        DEBUG = 10
        NOTSET = 0
注意:
1)如果默认的日志级别设成INFO,那么低于INFO的日志将不会被写,比如DEBUG信息不会被写;
2)如果这个日志不再被用了,需要remove掉其handler,否则它会常驻内存,引起混乱。

参考:https://github.com/hilqiqi0/AI/blob/master/4.crawler/testLogger.py


反反爬的策略:
        1)User-Agent池;
        2)代理服务器池;
        3)CookieJar等的管理;
        4)协议的细节考虑,如:需要大量的实践经验总结的
                  抓取数据时不处理CSS,JS等;
                  nofollow属性;css的display属性;探测陷阱;
                  验证refer locator等;
        5)使用分布式的多机策略;爬慢点,把爬虫放到访问频繁的主站IP子网下,如教育网;
        6)使用了规则来批量爬取,需对规则进行组合;
        7)验证码的搞定:机器学习,图像识别;
        8)尽可能遵守Robots协议;


CAP理论:CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性)、Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。
分布式系统的CAP理论:理论首先把分布式系统中的三个特性进行了如下归纳:
● 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
● 可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
● 分区容错性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,“就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
《7周7数据库》


去重的操作:
        已爬队列,当前这个页面处理时需要在已爬队列中做一次去重;
        待爬队列,为了保证队列里url的唯一性,这里需要在待爬队列中去重;

说明:
        1)待爬队列则既需要append,也需要pop;已爬队列中只有append操作;
        2)爬虫开始于向待爬队列中append一个seedUrl;结束于待爬队列为空时;
        3)在做去重的比较时,可以比较HASH之后的结果;如果数据量巨大的话,可以使用多次HASH来避免碰撞;3次HASH;
     
在生产环境中,一般使用Redis数据库来做去重操作;Redis是一种内存数据库,URL,URL哈希值,及抓取到的数据等保存在其中;在数据量大的时候,使用这种数据库的解决方案效率会高很多;缺点是还有硬件的限制,数据还是需要考虑在内存中的时效性和安全性;


安装Scrapy:
        conda install scrapy
制作一个Scrapy爬虫项目的步骤:
        1.创建项目:scrapy startproject tencentSpider
        2.进到下一层目录:cd     tencentSpider
        3.创建爬虫:scrapy genspider tencent hr.tencent.com
启动一个具体的爬虫
        scrapy crawl tencent
要让我们的爬虫程序能够正式的抓取数据,我们需要修改:
        setttings.py 设置
                1)注释掉Robots协议;
                2)打开Headers选项,添加UA;
                3)打开PIPELINES,准备保存数据;
        items.py 保存item的映射
                添加将来要抓取数据的信息:
                positionName = scrapy.Field() #名称
                positionLink = scrapy.Field() #详情链接
                positionType = scrapy.Field() #类别
        pipelines.py 保存的逻辑
                完善process_item保存数据的方法;
                tecent.py,抓取页面信息和继续跳转的逻辑
                /html/body/div[3]/div[1]/table/tbody/tr[2]
                /html/body/div[3]/div[1]/table/tbody/tr[2]/td[1]/a
                /html/body/div[3]/div[1]/table/tbody/tr[2]/td[2]
                https://hr.tencent.com/position.php?keywords=python&start=0#a
                https://hr.tencent.com/position.php?keywords=python&start=10#a
                https://hr.tencent.com/position.php?keywords=python&start=20#a

参考代码:招聘信息(https://github.com/hilqiqi0/AI/tree/master/4.crawler/tencentSpider

补充说明:
1)如果需要在Scrapy框架中去做proxy,可以在Downloadermiddler中对process_request方法做扩充:
       # 如果想要添加代理服务器的功能,可以在这里来扩充
       # proxy = random.choice(proyPool) #proyPool可以从setting.py中取出来
       # if proxy["user_passord"] is not None:
       #     proxy["user_passord"]=base64.baseEncode(proxy["user_passord"])
       # 在这里参见我们使用代理服务器的代码去调用代理服务器的方法去完成请求
注意: 别忘了打开setting.py中downloader中间件的设置:
DOWNLOADER_MIDDLEWARES = {
        'tencentSpider.middlewares.TencentspiderDownloaderMiddleware': 543,
}
2) 生成一个具体的爬虫时,可以使用:
       scrapy genspider -t crawl tencent2 hr.tencent.com
       #Created spider 'tencent2' using template 'crawl' in module:
       #  tencentSpider2.spiders.tencent2
CrawlSpider是Spider的派生类,Spider累的设计原则是只爬取strat_urls列表中的网页,而CrawlSpider定义了一些rule(规范)来提供link获取机制,从而更方便的抓取新的link的信息,具体的使用参见:
LinkExtractor的实现;
    allow=(),
    deny=(),
    allow_domains=(),
    deny_domains=(),
    restrict_xpaths=()

参考代码:招聘信息(https://github.com/hilqiqi0/AI/tree/master/4.crawler/tencentSpider2

Scrapy-Redis:
    Scrapy是一个爬虫框架;Scrapy-Redis能够很方便的实现Scrapy的分布式爬虫框架;提供了以Redis为基础的组件。


框架:
        优点:帮助我们快速的搭建一个系统,把一些繁琐的有一定模式的事情已经替我们做完了,提高开发效率;
        缺点:学习成本有时比较高,框架自身固有的缺陷需要我们自己想办法解决,所以需要找一些靠谱的开源框架学习,这样收益更大;


综合爬虫小项目:

猫眼TOP100(进程池、锁、函数包装器、mysql、logging日志)
       https://github.com/hilqiqi0/AI/tree/master/4.crawler/maoyantop100

高清壁纸下载(Scrapy + Mysql)
        https://github.com/hilqiqi0/AI/tree/master/4.crawler/PythonCrawler-Scrapy-Mysql-File-Template-master
        注:爬取起始地址:http://desk.zol.com.cn/fengjing/1920x1080/1.html

附录:目录

        人工智能(crawler)—— 目录汇总

猜你喜欢

转载自blog.csdn.net/qq_27297393/article/details/82251006