爬虫学习笔记

爬虫学习笔记

爬虫的概念

模拟浏览器发起请求,获取响应数据

爬虫的流程

url--->响应内容--->抓取数据--->保存到数据库

爬虫要根据当前URL地址对应的响应为准,当前URL地址的elements的内容和URL的响应不一样

当前URL地址对应的响应中
其他URL地址对应的响应中
    比如ajax请求中
js生成的   
    部分数据在响应中
    全部通过js生成

URL组成部分

形式   scheme://host[:port#]/path/…/[?query-string][#anchor]

scheme:协议(例如:http, https, ftp)
host:服务器的IP地址或者域名
port:服务器的端口(如果是走协议默认端口,80  or    443)
path:访问资源的路径
query-string:参数,发送给http服务器的数据
anchor:锚(跳转到网页的指定锚点位置)
http://localhost:4000/file/part01/1.2.html
http://item.jd.com/11936238.html#product-detail

requests中的解决编解码的方法

response.content.decode()
response.content.decode('gbk')
response.text

使用代理IP

-准备一堆的ip地址,随机选择一个ip使用

-如何随机选择代理ip,让使用次数比较少的有更大可能被用到

    -{‘ip’:ip,'times':0}
    -[{},{},{}]对这个ip列表进行遍历

Requests相关

http://docs.python-requests.org/zh_CN/latest/user/quickstart.html

正则使用的注意点

-re.findall("a(.*?)","str),能够返回括号中的内容,括号前后的内容祈祷定位和过滤的效果
-原始字符串r,待匹配字符串中有反斜杠\的时候,会让转义效果失效
-点号.默认匹配不到换行符\n
-\s能匹配到空白字符,不仅仅包含空格,还有\t|\r\n

Python compile() 函数

将一个正则表达式编译成python可识别的模式,这个模式的方法有findall(),sub()


描述

compile() 函数将一个字符串编译为字节代码。

语法

以下是 compile() 方法的语法:

compile(source, filename, mode[, flags[, dont_inherit]])

参数

  • source – 字符串或者AST(Abstract Syntax Trees)对象。。
  • filename – 代码文件名称,如果不是从文件读取代码则传递一些可辨认的值。
  • mode – 指定编译代码的种类。可以指定为 exec, eval, single。
  • flags – 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。。
    • 1).re.I(re.IGNORECASE): 忽略大小写
    • 2).re.M(MULTILINE): 多行模式,改变’^’和’$’的行为
    • 3).re.S(DOTALL): 点任意匹配模式,改变’.’的行为
    • 4).re.L(LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
    • 5).re.U(UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
    • 6).re.X(VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释
  • flags和dont_inherit是用来控制编译源码时的标志

返回值

返回表达式执行结果。

xpath学习重点

  • 正则如何进行非贪婪匹配,在div标签中的数据如何通过正则取出来

    • *? +?
    • re.findall(“
      . ?
      (.?)
      “,str) 返回列表,没有匹配到就是空列表
      xpath如何获取文本,如何获取任意标签下的文本
    • a/text() 只能获取a下的文本
    • a//text() 能够获取a下的和a包含的标签的文本
    • a[text()=”下一页”]
      xpath如何获取属性,如何对标签进行定位
    • a/@href
    • div[@class=’b’]
      xpath中//有什么用
    • //自最前面的时候,表示html中任意位置开始选择
    • div//* 放在节点后面的时候,能够选择当前节点下的所有的标签
      xpath获取某一个或者某几个
    • //a[1] 第一个
    • //a[last()] 最后一个
    • //a[position()<=3]
    • //a[1]|//a[3]
      xpath的包含
      //div[contains(@class,’i’)] # class属性里包含“i”的内容

    lxml如何如何使用,如何把lxml处理之后的内容转化为字符串

    • from lxml import etree
    • element = etree.HTML(bytes、str) #把字符串转化为element对象
    • etree.tostring(element) #把element对象转化为字符串
    • element.xpath(“xpath_str”)

实现爬虫的套路

  • 准备url
    • 准备start_url
    • url地址规律不明显,总数不确定
    • 通过代码提取下一页的url
      • xpath
      • 寻找url地址,部分参数在当前的响应中(比如,当前页码数和总页码数在当前响应中)
    • 准备url_list
    • 页码总数明确
    • url地址规律明显
  • 发送请求,获取响应
    • 添加随机的User-Agent,反反爬虫
    • 添加随机的代理ip
    • 在对方判断出我们是爬虫后,应该添加更多的headers字段包括cookie
    • cookie的处理可以使用session解决
    • 准备一堆的cookie,组成cookie池
    • 如果不登录
      • 准备刚开始能够成功请求对方网站的cookie,即接收对方设置在response的cookie
      • 下一次请求的时候,使用之前的列表中的cookie来请求
    • 如果登陆
      • 准备多个帐号
      • 使用程序获取多个帐号的cookie
      • 之后请求登陆之后才能访问的网站随机的选择cookie
  • 提取数据
    • 确定数据的位置
    • 如果数据在当前的url地址中
      • 提取的是列表页的数据
      • 直接请求列表页的url地址,不用进入详情页
      • 提取的是详情页数据
      • 1、确定url
      • 2、发送请求
      • 3、提取数据
      • 4、返回保存
    • 如果数据不在当前的url地址中
      • 在其他的响应中,寻找数据的位置
      • 1、从network中从上到下找
      • 2、使用Chrome中的过滤条件,选择除了js,css,哦买噶,之外的按钮
      • 3、使用Chrome的search all file,搜索数字和英文
    • 数据的提取
    • xpath,从html中提取整块的数据,先分组,之后每一组再提取
    • re,提取max_time,price,html中的json字符串
    • json
  • 数据保存
    • 保存在本地,text,json,csv
    • 保存在数据库

“如今你的气质里,藏着你走过的路,读过的书和爱过的人。” ——《卡萨布兰卡》

selenium和phantomJS

# 用户名
username    = 'dotcoo'
# 密码
password    = 'dotcoo'                    
# 软件ID,开发者分成必要参数。登录开发者后台【我的软件】获得!
appid       = 4916                         
# 软件密钥,开发者分成必要参数。登录开发者后台【我的软件】获得!
appkey      = '7b392d65faf3ca3167be1ae94448e3e5'    

MongoDB

mongodb插入数据

  • db.collection.insert({}),_id存在会报错
  • db.collection.save({}),_id存在会更新

mongodb的更新操作

  • db.collection.update({name:”ming”},{name:”hong”}),把ming更换为hong
  • db.collection.update({name:”hong”},{$set:{name:”ling”}}), 指定把hong替换为ling
  • {multi:true}更换多条

删除

  • db.collection.remove({name:”hong”},{justOne:true})
  • 默认会删除多条满足的数据,{justOne:true}只删除一条

count方法

  • db.collection.find().count()
  • db.collection.count({})

投影

  • 选择返回结果的字段
  • db.collection.find({条件},{name:1,_id:0})
    • 1、_id默认会显示。置为0不显示
    • 2、除了_id之外的其它字段,需要显示则写1,不显示不写,不能写0

group的注意点

  • $group 对应的字典中有几个键,结果中就有几个键
  • 分组依据需要放到_id 后面
  • 取不同字段的值需要使用,例如”gender,$age”
  • 取字典嵌套的字典中的值时$_id.country
  • 能够同时按照多个健将进行分组 {group:{_id:{country:" group:{_id:{country:" country",province:"$province”}}}
    • 结果是:{_id:{country:”“,province:”“}}

mongodb mysql redis的区别和使用场景

  • mysql是关系型数据库,支持事物
  • mongodb,redis非关系型数据库,不支持事物
  • mysql,mongodb,redis的使用根据如何方便进行选择
    • 希望速度快的时候,选择mongodb或者是redis
    • 数据量过大的时候,选择频繁使用的数据存入redis,其他的存入mongodb
    • mongodb不用提前建表建数据库,使用方便,字段数量不确定的时候使用mongodb
    • 后续需要用到数据之间的关系,此时考虑mysql

爬虫数据去重,实现增量式爬虫

  • 使用数据库建立关键字段(一个或者多个)建立索引进行去重
  • 根据url地址进行去重
    • 使用场景:
    • url地址对应的数据不会变的情况,url地址能够唯一判别一个条数据的情况
    • 思路
    • url存在redis中
    • 拿到url地址,判断url在redis的url的集合中是够存在
    • 存在:说明url已经被请求过,不再请求
    • 不存在:url地址没有被请求过,请求,把该url存入redis的集合中
    • 布隆过滤器
    • 使用多个加密算法加密url地址,得到多个值
    • 往对应值的位置把结果设置为1
    • 新来一个url地址,一样通过加密算法生成多个值
    • 如果对应位置的值全为1,说明这个url地址已经抓过
    • 否则没有抓过,就把对应位置的值设置为1
  • 根据数据本省进行去重
    • 选择特定的字段,使用加密算法(md5,sha1)讲字段进行假面,生成字符串,存入redis的集合中
    • 后续新来一条数据,同样的方法进行加密,如果得到的字符串在redis中存在,说明数据存在,对数据进行更新,否则说明数据不存在,直接插入

组成部分介绍:

  • Scrapy Engine:
    负责组件之间数据的流转,当某个动作发生时触发事件
  • Scheduler:
    接收requests,并把他们入队,以便后续的调度
  • Downloader:
    负责抓取网页,并传送给引擎,之后抓取结果将传给spider
  • Spiders:
    用户编写的可定制化的部分,负责解析response,产生items和URL
  • Item Pipeline:
    负责处理item,典型的用途:清洗、验证、持久化
  • Downloader middlewares:
    位于引擎和下载器之间的一个钩子,处理传送到下载器的requests和传送到引擎的response(若需要在Requests到达Downloader之前或者是responses到达spiders之前做一些预处理,可以使用该中间件来完成)
  • Spider middlewares:
    位于引擎和抓取器之间的一个钩子,处理抓取器的输入和输出
    (在spiders产生的Items到达Item Pipeline之前做一些预处理或response到达spider之前做一些处理)

你可能感兴趣的:(爬虫笔记,爬虫笔记)