初学Python之爬虫

爬虫学习笔记

  • 什么是爬虫?

    • 爬虫就是:模拟客户端(浏览器)发送网络请求,获取响应,按照规则提取数据的程序
    • 模拟客户端(浏览器)发送网络请求:照着浏览器发送一模一样的请求,获取和浏览器一模一样的数据
  • 爬取的数据去哪了

    • 呈现出来:展示在网页上,或者是展示在app上
    • 进行分析:从数据中寻找一些规律
  • 需要的软件和环境

    • Python3
      安装Python一般有两种方法:1.去Python官网下载对应系统的安装包安装;2.通过anaconda套件安装Python环境。据说anaconda很不错,可以很方便地解决多版本python并存、切换以及各种第三方包安装问题,所以我就选了它。
    • Pycharm
      估计是最受欢迎的Python的集成开发环境,专业版是收费的,试用期30天,社区版免费,对我这种初学者应该也够用了。(注意安装后要配置一下anaconda的环境)
    • Chrome浏览器或者Firefox
      分析网络请求用的
  • 浏览器的请求

    • url
      在chrome中点击检查,点到network
      url=请求的协议+网站的域名+资源路径+参数
    • 浏览器请求url地址
      当前url对应的响应+js+css+图片——>elements中的内容
    • 爬虫请求url地址
      当前url对应的响应
      Elements的内容和爬虫获取到的url地址响应不同,爬虫中需要以当前url地址对应的响应为准提取数据
    • 当前url地址对应的响应在哪里
      1. 从network中找到当前的url地址,点击response
      2. 在页面上右键点击显示网页源码
  • 认识HTTP、HTTPS

    • HTTP:超文本传输协议
      以明明的形式传输
      效率更高,但是不安全
    • HTTPS:HTTP+SSL(安全套接字层)
      传输之前数据先加密,之后解密获取内容
      效率较低,但是安全
    • Get请求和post请求的区别
      Get请求没有请求体,post请求有,get请求把数据放到url地址中
      Post请求常用于登录注册,
      Post请求携带的数据量比get请求大,多,常用于传输大文本的时候
  • HTTP协议之请求

    1. 请求行
    2. 请求头
      User-Agent:用户代理:对方服务器能够通过User_Agent知道当前请求对方资源的是什么浏览器
      如果我们需要模拟手机版的浏览器发送请求,对应的,就需要把user_agent改成手机版
      Cookie:用来存储用户信息的,最终每次请求会被携带上发送给对方的浏览器
      要获取登录后才能访问的页面
      对方的服务器会通过Cookie来判断我们是否是一个爬虫
    3. 请求体
      携带数据
      Get请求没有请求体
      Post请求有请求体
  • HTTP协议之响应

    1. 响应头
      Set-Cookie:对方服务器通过该字段设置cookie到本地
    2. 响应体
      url地址对应的响应
  • requests模块的学习

    • 使用之前先安装requests模块
      pip install requests

    • 发送get,post请求,获取响应

response=requests.get(url)  # 发送get请求,请求url地址
 response=requests.post(url,data={请求体的字典})  #  发送post请求,请求url地址对应的响应
  • response的方法
    • response.text
      该方式往往会出现乱码,出现乱码使用
response.encoding=“utf-8”
response.content.decode()
  • 把响应的二进制字节流转化为str类型
response.request.url  # 发送请求的url地址
 response.url  # response响应的url地址
 response.request.headers  # 请求头
 response.headers  # 响应头
  • 获取网页源码的正确打开方式(通过下面三种方式一定能够获取到网页正确解码之后的字符串)
  1. response.content.decode()
  2. response.content.decode(“gbk”)
  3. response.text
  • 发送带header的请求
headers=
{ “User-Agent”:“ Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1” 
“Referer”: “https://fanyi.baidu.com/}

response=requests.get(url,headers=headers)
  • 使用超时参数
# 3秒内必须返回响应,否则会报错
requests.get(url,headers=headers,timeout=3)
  • retrying模块学习
    首先 pip install retrying
from retrying import retry

@retry(stop_max_attempt_number=3)
def fun1():
  print(“this is func1”)
  raise ValueError(“this is test error”)
  • 处理cookie相关的请求

    • 直接携带cookie请求url地址
      1.把cookie放在headers中
      Headers={“User_Agent”:“……”“Cookie”:“cookie字符串”}
      2.cookie字典传给cookies参数
      requests.get(url,cookies=cookie_dict)
  • 先发送post请求,获取cookie,带上cookie请求登录后的页面

# 1.session具有的方法和requests一样
session = requests.session()
# 2.服务器设置在本地的cookie会保存在session
session.post(url,data,headers)
# 3.会带上之前保存在session中的cookie,能够请求成功
session.get(url)
  • 数据提取方法

    • jison
      数据交换格式,看起来像Python类型的字符串
      使用json之前需要导入
    • 哪里会返回json的数据
      1.浏览器切换到手机版
      2.抓包APP
  • Json.loads
    把json字符串转化为Python类型
    json.loads(json字符串)

  • Json.dumps
    把Python类型转化为json字符串
    json.dumps({“a”=”a”,”b”=”2”})

  • json.dumps(ret1,ensure_ascii=False,indent=2)
    ensure_ascii:让中文显示成中文
    indent:能够让下一行在上一行的基础上空格

  • xpath和lxml
    xpath
    一门从html中提取数据的语言
    xpath语法
    Xpath helper插件:帮助我们从elements中定位数据

  1. 选择节点(标签)
    /html/head/meta:能够选中html下的head下的所有的meta标签
  2. //:能够从任意节点开始选择
    //li:当前页面上的所有的li标签
    /html/head//link:head下的所有的link标签
  3. @符号的用途
    选择具体某个元素://div[@class=’feed-infinite-wrapper’]/ul/li
    选择class=’feed-infinite-wrapper’的div下的ul下的li
    a/@href:选择a的href的值
  4. 获取文本
    /a/text():获取a下的文本
    /a//text():获取a下的所有文本
  5. 当前
    “./a”当前节点下的a标签
  • lxml
    安装:pip install etree
    使用
from lxml import etree
 element = etree.HTML(“html字符串”)
 element.xpath(“”)
  • 写爬虫的讨论
  1. url
    知道url地址的规律和总的页码数:构造url地址的列表
    star_url
  2. 发送请求,获取响应
    requests
  3. 提取数据
    返回json字符串:json模块
    返回的是html字符串:lxml模块配合xpath提取数据
  4. 保存
  • 案例(糗事百科)
# coding=utf-8
from lxml import etree
import requests
import json



class QiuBaiSpider:
    def __init__(self):
        self.url_temp = "https://www.qiushibaike.com/8hr/page/{}/"
        self.headers = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36"}

    def get_url_list(self):# 根据url地址的规律,构造url_list
        url_list = [self.url_temp.format(i) for i in range(1,14)]
        return url_list

    def parse_url(self,url):
        print("now parsing:",url)
        response = requests.get(url,headers=self.headers)
        return response.content.decode()

    def get_content_list(self,html_str):
        html = etree.HTML(html_str)
        # 1.分组
        div_list = html.xpath("//div[@id='content-left']/div")
        content_list = []
        for div in div_list:
            item = {}
            item["author_name"] = div.xpath(".//h2/text()")[0].strip() if len(div.xpath(".//h2/text()"))>0 else None
            item["content"] = div.xpath(".//div[@class='content']/span/text()")
            item["content"] = [i.strip() for i in item["content"]]
            item["stats_vote"] = div.xpath(".//span[@class='stats-vote']/i/text()")
            item["stats_vote"] = item["stats_vote"][0] if len(item["stats_vote"])>0 else None
            item["stats_comments"] = div.xpath(".//span[@class='stats-comments']//i/text()")
            item["stats_comments"] = item["stats_comments"][0] if len(item["stats_comments"]) > 0 else None
            item["img"] = div.xpath(".//div[@class='thumb']//img/@src")
            item["img"] = "https:"+item["img"][0] if len(item["img"])>0 else None
            content_list.append(item)
        return content_list

    def save_content_list(self,content_list): # 保存
        with open("qiubai.txt","a",encoding="utf-8") as f:
            for content in content_list:
                f.write(json.dumps(content,ensure_ascii=False))
                f.write("\n")
        print("保存成功")



    def run(self):# 实现主要逻辑
        # 1.根据url地址的规律,构造url_list
        url_list = self.get_url_list()
        # 2.发送请求,获取响应
        for url in url_list:
            html_str = self.parse_url(url)
            # 3.提取数据
            content_list = self.get_content_list(html_str)
            # 4.保存
            self.save_content_list(content_list)

if __name__ == '__main__':
    qiubai = QiuBaiSpider()
    qiubai.run()

在这里插入图片描述