码迷,mamicode.com
首页 > 其他好文 > 详细

爬虫基础总结

时间:2019-10-12 22:35:11      阅读:98      评论:0      收藏:0      [点我收藏+]

标签:sd卡   鼠标   序列化   开启   mon   item   shell   验证   red   

爬虫设计

爬虫基本包含 爬虫调度器,URL管理器(已爬与待爬),HTML下载器(获取网络信息),HTML解析器,数据存储器五个部分。

0x1 网站调研

了解网站基本特点,设计相应的爬取方案
探测反爬措施,设计对应反反爬方式

  • 查看网站的robot.txt与sitemap,了解网站限制内容
    • User-agent: 指定对哪些爬虫生效
    • Disallow: 指定不允许访问的网址
    • Allow: 指定允许访问的网址
  • 识别网站使用的技术(builtwith),了解内容大概以什么形式加载
  • 估计网站相应页面的规模(利用Google的site:XXX搜索相应网站目录下的返回结果数量)
  • 了解网站所有者
  • 查看网站结构,了解网站数据交互的接口方式,确定目标数据的位置和返回结构
  • 分析网站访问的身份控制与源控制的方法(如header与cooike,RefererHost
    • 两次重复 登陆/注册/访问 某一个页面,对比两次访问的信息区别,找到变化的与不变的参数,针对每一个参数寻找获取的方法,部分不变的参数有可能可以不添加;
    • 一些页面信息可能包含了需要提交的参数数值;一些前面的请求返回信息将提供给之后请求的参数,但是可能参数名变化而参数值不变;一些参数在js代码中函数被生成(可以使用pyV8执行JS函数直接获得)。
  • 查看移动端(可通过修改agent来实现)呈现的网站网页
  • 查看网站提供的API接口以及返回的信息内容
  • 简单爬取尝试,探测网站存在的反爬策略,设计爬取策略
  • 动态生成页面内容可能导致爬虫认为未处理而持续停留在一个页面,陷入爬虫陷阱,需要设置最大深度。
  • 根据网站动态交互的方式,选择使用单网页下载或浏览器自动渲染的方式
  • 注意事项
    • 整个过程中需要保证编码维持为utf-8
    • 正则表达式的使用:(.*?)用于获取匹配位置的括号匹配的信息
    • 使用xpath时候,可以结合chrome浏览器的元素copy到xpath功能。(在copy中还可以复制源码,确定选择器),复制要完整,尤其注意网页上类与ID中出现空格之类的东西。
      //定位根节点位置,/向下寻找,/text()获取文本信息,/@XXX选择元素
      导入模块From lxml import etree后使用Selector = etree.HTML(XXX) 转换成xpath识别的文本类型。在使用content = selector.xpath(‘//div[@id]/ul’)获取文本信息。
      如果出现同一个标签下需要的元素的ID具有相同开头,则使用(‘//div[start-with(@id,”test)]/text())可以实现目的。但是直接使用/text()会使得标签中套的标签不能被获取。此时需要先大后小:data = selector.xpath(‘//div[@id]’)后使用content = data.xpath(‘string(.)’)

0x2 数据提取

推荐使用lxml(解析速率比beautifulsoup快)
对经常分析的更新速率慢的网站建议进行网页缓存,以便于增加或调整需要提取的数据
分析同一URL的数据是否有不同,是否存在增量式爬取

  • 数据库准备,推荐使用MongoDB 网页/数据去重

  • 设计数据库结构

  • 定位网页元素,提取目标数据 推荐使用lxml

  • 分析网页中的动态内容(AJAX方式,GWT方式)

  • 根据网站数据交互的URL,调整参数,以获得更多的信息

  • 智能化解析工具

  • 使用urlretrieve函数实现多媒体文件抽取,并设置回调函数

    import urllib
    def schedule(blocknum, blocksize, totalsize):
        per = 100.0 * blocknum * blocksize / totalsize
        if per > 100:
            per = 100
        print("[+] Now get: %d" % per)
    
    urllib.urlretrieve(img_url, filename, schedule)
  • 使用集合set的方式进行内存去重,可以使用数据库去重,使用缓存数据库Redis去重,
    可以在此基础上使用MD5处理URL取中间28位字符作为比对信息,可以将未爬取的已爬的信息序列化存储,保存信息以备后续使用。

  • 增量爬取信息一定要掌握去重的工作!!!

0x3 反反爬虫措施

  • 验证码处理:图片识别OCR、 人工打码API、 模拟鼠标滑动
  • 速率限制:随机休眠(time.sleep)
  • IP限制:使用代理 requests.get(URL, procies={‘http‘: ‘http://IP.port‘}, ‘https‘: ‘http://IP.port‘}) 个人使用,60-70个代理IP即可。
  • 用户访问限制:培育多个账户
  • 字体反爬机制,即网站定义了字体文件,然后进行相应的查找替换,在前端看起来,是没有任何差异的。

0x4 加速下载

爬取同一个网站下的网页,一般两次下载间间隔至少1s
celery 专用的信息传输工具

  • 多线程
  • 多进程

0x5 APP数据采集

模拟器+burpsuit

  • 修改模拟器中无线网络,长按后添加代理,设置为本机ip
  • 在burpsuit中设置Proxy Listeners添加监听端口信息
  • 使用模拟器的浏览器连接到代理的端口,并下载证书,也可以直接通过bp生成后给模拟器
  • 将文件后缀der修改为cer,设置->安全->从SD卡安装证书

PC端热点+wireshark

  • PC端创建无线热点
  • 手机端连接,开启wireshark分析相关文件

scrapy

参考:https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html

基本流程

  1. 创建工程
  2. 定义提取项
  3. 写爬虫获取并提取数据
  4. 写pipeline存储提取的数据

基本使用

scrapy startproject tutorial   创建工程
    scrapy.cfg: the project configuration file   #是这个工程的根目录所在层
    tutorial/: the project’s python module, you’ll later import your code from here.
    tutorial/items.py: the project’s items file.  # 定义要爬取存储的项
    tutorial/pipelines.py: the project’s pipelines file.
    tutorial/settings.py: the project’s settings file.  #包含工程的基本设置信息
    tutorial/spiders/: a directory where you’ll later put your spiders.

from scrapy.item import Item, Field 每个Item有多个Field对象
class DmozItem(Item):
title = Field()

scrapy genspider name <domain>  创建爬虫  爬虫的文件名不能与项目名字重合

#爬虫定义
from scrapy.spider import BaseSpider
name: identifies the Spider.
start_urls: is a list of URLs where the Spider will begin to crawl from.
? parse() is a method of the spider, which will be called with the downloaded Response object of each start URL. The response is passed to the method as the first and only argument.

scrapy crawl mininova -o scraped_data.json -t json  输出为json格式
scrapy crawl mininova -o teachers.csv               输出为csv格式
scrapy crawl mininova

爬虫运行前,关闭setting里面的robots协议 ROBOTSTXT_OBEY

需要存储时需要开启ITEM_PIPELINES
ITEM_PIPELINES = {
   'test_taobao.pipelines.TestTaobaoPipeline': 300,
}
启动 DOWNLOADER_MIDDLEWARES 也是类似的,其后的数值是执行的先后顺序,从低到高

shell方式尝试 用于调试
scrapy shell "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/"

BeautifulSoup

从HTML或XML文件中提取数据的Python库
参考 https://www.cnblogs.com/haiyan123/p/8317398.html

基本使用

from bs4 import BeautifulSoup
soup=BeautifulSoup(html_doc,'lxml') #具有容错功能
soup.find_all(name="a")
soup.find_all(text="The Dormouse's story"))  #按照文本来找

xpath

Chrome 给我们提供了一键获取 xpath 地址的方法(右键->检查->copy->copy xpath)

基本使用

  • / 从根节点选取。
  • // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
  • . 选取当前节点。
  • .. 选取当前节点的父节点。
  • @ 选取属性。 标签[@属性名=‘属性值‘]
  • 提取标签里面的内容,表达式: //text()
  • 包含HTML标签的所有文字内容提取:string() "string(//div[@class=‘post-content‘])"
  • //td: selects all the elements
  • /html/head/title/text(): selects the text inside the aforementioned element.</li> <li>//div[@class="mine"]: selects all div elements which contain an attribute class="mine"</li> <li>/bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。</li> <li>/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。</li> <li>/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。</li> </ul> <h2 id="css">CSS</h2> <h3 id="基本使用-3">基本使用</h3> <ul> <li>".class"</li> <li>"#id"</li> <li><code>*</code> 所有元素</li> <li>:optional 用于匹配可选的输入元素</li> <li>:link a:link 选择所有未访问链接</li> <li>:visited a:visited 选择所有访问过的链接</li> </ul><p><a href="http://www.mamicode.com/info-detail-2805824.html" title="爬虫基础总结,mamicode.com" style="color:#ffffff" target="_blank">爬虫基础总结</a></p><p>标签:<a href='http://www.mamicode.com/so/1/sd%e5%8d%a1' title='sd卡'>sd卡</a>   <a href='http://www.mamicode.com/so/1/%e9%bc%a0%e6%a0%87' title='鼠标'>鼠标</a>   <a href='http://www.mamicode.com/so/1/%e5%ba%8f%e5%88%97%e5%8c%96' title='序列化'>序列化</a>   <a href='http://www.mamicode.com/so/1/%e5%bc%80%e5%90%af' title='开启'>开启</a>   <a href='http://www.mamicode.com/so/1/mon' title='mon'>mon</a>   <a href='http://www.mamicode.com/so/1/item' title='item'>item</a>   <a href='http://www.mamicode.com/so/1/shell' title='shell'>shell</a>   <a href='http://www.mamicode.com/so/1/%e9%aa%8c%e8%af%81' title='验证'>验证</a>   <a href='http://www.mamicode.com/so/1/red' title='red'>red</a>   </p><p>原文地址:https://www.cnblogs.com/joeat1/p/11664140.html</p></span> </div> <div id="divcomment"> <div> <div class="divtextaligncenter paddingright2 overflowauto"> <div class="detailcai" id="infono" onclick="infono_click();"> <div class="detailcai1 colorboldlan"> 踩</div> <div class="detailcai2 colorboldlan"> (<span id="spanNo">0</span>)</div> </div> <div class="detailzan" id="infoyes" onclick="infoyes_click();"> <div class="detailzan1 colorboldHong"> 赞</div> <div class="detailzan2 colorboldHong"> (<span id="spanYes">0</span>)</div> </div> </div> <div class="divtextalignright margintop10"> <div class="width100bi paddingleft10right10"> <span id="spanYesContent" class="colorboldHong"></span>  <span id="spanNoContent" class="colorboldlan"></span>  <span id="spanBadContent" class="colorboldHong"> </span> </div> </div> </div> <div class="divtextalignright margintop10"> <span class="detailjubao" id="infobad" onclick="infobad_click();">举报</span> </div> <script type="text/javascript"> mamicode_adload('content_after');</script> <div id="comment" class="divtextalignleft margintop20"> <div class="detailpinglun1"> <span class="detailpinglun2 title6">评论</span> <span class="detailpinglun3">一句话评论(<span id="commentCount" class="colorboldHong">0</span>)</span> </div> <div class="paddingtop20"> <div id="commentlistend" name="commentlistend" class="divtextaligncenter margintop20"> <span id="lblpage"></span> </div> </div> <div class="margintop20"> <form method="post" action="/ajaxjs/info_detail_commentadd.aspx"> <div class="divtextalignleft paddingtop20"> <div id="commenthf" class="divbackgroundcolor1"> </div> <div> <textarea name="tbcommentcontent" id="tbcommentcontent" class="tb" disabled="disabled" style="width: 680px; height: 120px;" ></textarea> </div> </div> <div class="divtextalignright paddingtop10 "> <span id="addCommentTishi" class="colorboldHong">登录后才能评论!</span> <span id="loginno"><input type="button" class="mbtn1" value="登录" onclick="location.href='http://member.mamicode.com/login.aspx?returnUrl='+document.URL.replace(new RegExp('&', 'g'), '(_)')" /></span> </div> </form> </div> </div> </div> <script type="text/javascript"> mamicode_adload('content_bottom');</script> </div> </div> <div class="width30bi divfloatright"> <div class="paddingbottom20"> <script type="text/javascript">(function(){document.write(unescape('%3Cdiv id="bdcs"%3E%3C/div%3E'));var bdcs = document.createElement('script');bdcs.type = 'text/javascript';bdcs.async = true;bdcs.src = 'http://znsv.baidu.com/customer_search/api/js?sid=8166352449904245503' + '&plate_url=' + encodeURIComponent(window.location.href) + '&t=' + Math.ceil(new Date()/3600000);var s = document.getElementsByTagName('script')[0];s.parentNode.insertBefore(bdcs, s);})();</script> </div> <script type="text/javascript"> mamicode_adload('right_top');</script> <div class="width99bi divborder"> <div class="divtitle"> <div id="infofile1_div1" class="divfloatleft divtitlefont"> 分享档案</div> <div class="divfloatright"> <a href="/infotimemore.html" title="分享档案更多" class="colorCheng">更多></a> </div> </div> <div class="divtextalignleft paddingleft10right10 margintop10bottom10 heightline30px"> <a class="taga" href="/info-time-20210729-1.html" target="_blank" title="2021年07月29日技术分享文章"> 2021年07月29日 (22)</a><br /> <a class="taga" href="/info-time-20210728-1.html" target="_blank" title="2021年07月28日技术分享文章"> 2021年07月28日 (40)</a><br /> <a class="taga" href="/info-time-20210727-1.html" target="_blank" title="2021年07月27日技术分享文章"> 2021年07月27日 (32)</a><br /> <a class="taga" href="/info-time-20210726-1.html" target="_blank" title="2021年07月26日技术分享文章"> 2021年07月26日 (79)</a><br /> <a class="taga" href="/info-time-20210723-1.html" target="_blank" title="2021年07月23日技术分享文章"> 2021年07月23日 (29)</a><br /> <a class="taga" href="/info-time-20210722-1.html" target="_blank" title="2021年07月22日技术分享文章"> 2021年07月22日 (30)</a><br /> <a class="taga" href="/info-time-20210721-1.html" target="_blank" title="2021年07月21日技术分享文章"> 2021年07月21日 (42)</a><br /> <a class="taga" href="/info-time-20210720-1.html" target="_blank" title="2021年07月20日技术分享文章"> 2021年07月20日 (16)</a><br /> <a class="taga" href="/info-time-20210719-1.html" target="_blank" title="2021年07月19日技术分享文章"> 2021年07月19日 (90)</a><br /> <a class="taga" href="/info-time-20210716-1.html" target="_blank" title="2021年07月16日技术分享文章"> 2021年07月16日 (35)</a><br /> </div> </div> <div class="width99bi margintop20 divborder"> <div class="divtitle"> <div id="infotop2_divtitle" class="divfloatleft divtitlefont">周排行</div> <div class="divfloatright"> <img src="/img/j01.jpg" width="14" height="14" alt="mamicode.com排行更多图片" /></div> <div class="divfloatright"> <a href="/info-toplist-11-2-1.html" id="infotop2_amore" title="周排行更多">更多</a></div> </div> <div> <ul> <li class="divullititle heightline25px divtextalignleft"><a href="/info-detail-3126753.html" title="分布式事务" target="_blank"> 分布式事务  <span class="colorlan">2021-07-29</span> </a> </li> <li class="divullititle heightline25px divtextalignleft"><a href="/info-detail-3126752.html" title="OpenStack云平台命令行登录账户" target="_blank"> OpenStack云平台命令行登录账户  <span class="colorlan">2021-07-29</span> </a> </li> <li class="divullititle heightline25px divtextalignleft"><a href="/info-detail-3126751.html" title="getLastRowNum()与getLastCellNum()/getPhysicalNumberOfRows()与getPhysicalNumberOfCells()" target="_blank"> getLastRowNum()与getLastCellNum()/getPhysicalNumberOfRows()与getPhysicalNumberOfCells()  <span class="colorlan">2021-07-29</span> </a> </li> <li class="divullititle heightline25px divtextalignleft"><a href="/info-detail-3126749.html" title="【K8s概念】CSI 卷克隆" target="_blank"> 【K8s概念】CSI 卷克隆  <span class="colorlan">2021-07-29</span> </a> </li> <li class="divullititle heightline25px divtextalignleft"><a href="/info-detail-3126748.html" title="vue3.0使用ant-design-vue进行按需加载原来这么简单" target="_blank"> vue3.0使用ant-design-vue进行按需加载原来这么简单  <span class="colorlan">2021-07-29</span> </a> </li> <li class="divullititle heightline25px divtextalignleft"><a href="/info-detail-3126746.html" title="stack栈" target="_blank"> stack栈  <span class="colorlan">2021-07-29</span> </a> </li> <li class="divullititle heightline25px divtextalignleft"><a href="/info-detail-3126745.html" title="抽奖动画 - 大转盘抽奖" target="_blank"> 抽奖动画 - 大转盘抽奖  <span class="colorlan">2021-07-29</span> </a> </li> <li class="divullititle heightline25px divtextalignleft"><a href="/info-detail-3126742.html" title="PPT写作技巧" target="_blank"> PPT写作技巧  <span class="colorlan">2021-07-29</span> </a> </li> <li class="divullititle heightline25px divtextalignleft"><a href="/info-detail-3126738.html" title="003-核心技术-IO模型-NIO-基于NIO群聊示例" target="_blank"> 003-核心技术-IO模型-NIO-基于NIO群聊示例  <span class="colorlan">2021-07-29</span> </a> </li> <li class="divullititle heightline25px divtextalignleft"><a href="/info-detail-3126737.html" title="Bootstrap组件2" target="_blank"> Bootstrap组件2  <span class="colorlan">2021-07-29</span> </a> </li> </ul> </div> </div> <script type="text/javascript"> mamicode_adload('right_bottom');</script> </div> <div class="divfloatclear"> </div> </div> <script type="text/javascript"> mamicode_adload('bottom');</script> <div class="width1000px divmargin0auto paddingtop20bottom20"> <div class="width1000px divborder margintop20"> <div class="youqingtitle"> <a title="友情链接">友情链接</a> </div> <div class="youqingcontent"> <a href='http://www.lightinit.com' target='_blank' title='互联网产品定制开发专家'>兰亭集智</a>   <a href='http://www.guozhihua.net/' target='_blank'>国之画</a>   <a href='http://tongji.baidu.com' target='_blank'>百度统计</a>   <a href='http://www.cnzz.com/' target='_blank'> 站长统计</a>   <a href='http://www.aliyun.com/' target='_blank'>阿里云</a>   <a href='http://www.cnplugins.com/' target='_blank'>chrome插件</a>   <a href="https://m.tiantingfm.com/list/" target='_blank'>新版天听网</a> </div> </div> </div> <div class="bottomdiv"> <div class="width1000px divmargin0auto paddingtop20"> <div class="height30px divtextalignleft"> <a href="/about.html" title="mamicode.com关于我们">关于我们</a> - <a href="/contactus.html" title="mamicode.com联系我们">联系我们</a> - <a href="/guest.html" title="mamicode.com留言反馈">留言反馈</a> </div> <div class="height30px divtextalignleft"> © 2014 <a href="http://www.mamicode.com" target="_blank" title="mamicode.com,技术分享">mamicode.com</a> 版权所有 <!--<a href="http://www.beian.miit.gov.cn" target="_blank">京ICP备13008772号-2</a>-->  联系我们:gaon5@hotmail.com </div> <div class="divtextalignleft"> <span class="colorlan">迷上了代码!</span> </div> <div class="paddingtop20"> <script> (function () { var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> <script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?c932f0b810213e2feccccbb987715fd6"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script> </div> </div> </div> <script type="text/javascript"> var mid = ''; var id = '2805824'; var idm = '92a887'; var commentitemcount = '0'; var memberhost = 'http://member.mamicode.com/'; prettyPrint(); </script> <script src="/js/infodetail.js" type="text/javascript" charset="utf-8"></script> <script src="/js/member.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript" src="/js/mamicodejs.js"></script> </body> </html>