IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python爬虫 -> 正文阅读

[Python知识库]python爬虫

爬虫心得

爬虫的最终目的是通过程序模拟用户上网,爬取目标网站的相关数据。那么,就需要有python数据结构的相关知识,主要涉及序列、元组和字典。

  • 序列

    序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。

    list1 = ['physics', 'chemistry', 1997, 2000]
    
  • 元组

    tup1 = ('physics', 'chemistry', 1997, 2000)
    
  • 字典

    dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
    
    #访问字典里的值
    dict['Name']
    #输出字典可打印的字符串表示	
    str(dict)
    

GET请求目标网站

  • 实现步骤:

    第一步:获取目标网站的url

    第二步:通过requests库发送get请求

    第三步:设置参数用来接收返回的网站

    第四步:通过xpath解析数据

  • 案例分析

    import requests
    from lxml import etree
    
    url="http://www.sxjybk.com/gdjy.htm"
    headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
    }
    resp=requests.get(url,headers=headers);
    resp.encoding=resp.apparent_encoding
    html=etree.HTML(resp.text);
    
    #获取总页数
    _pageNum=html.xpath("/html/body/div[3]/div[3]/div/span/span[9]/a/text()")
    pageNum="".join(_pageNum);#数组转字符串
    #print(pageNum)
    currentPage=int(pageNum)
    while currentPage>0:
        page_url = "http://www.sxjybk.com/gdjy/"+str(currentPage)+".htm"
        #print(page_url)
        #currentPage=currentPage-1
        _resp = requests.get(page_url, headers=headers);
        _resp.encoding = _resp.apparent_encoding
        html = etree.HTML(_resp.text);
        a_list=" ".join(html.xpath("/html/body/div[3]/div[3]/ul/li/a[2]/@href"))
        #print(a_list)
        news_list=a_list.replace("..","http://www.sxjybk.com/").split()
        #print(news_list)
        for href in news_list:
            #print(href)
            resp = requests.get(href, headers=headers);
            resp.encoding = resp.apparent_encoding
            item_html = etree.HTML(resp.text)
            #print(item_html)
            content = "".join(item_html.xpath("//html/body/div[3]/form/div[3]/div[1]/div/p/text()"))
            title = "".join(item_html.xpath("/html/body/div[3]/form/div[1]/span[2]/text()"))
            source = "".join(item_html.xpath("/html/body/div[3]/form/div[1]/div[1]/span[1]/text()")).strip().replace("来源:"," ")
            date_time = "".join(item_html.xpath("/html/body/div[3]/form/div[1]/div[1]/span[3]/text()")).replace('年', '-').replace('月', '-').replace('日', '')
            #print(date_time)
            if content!="":
                edu_info = {
                    "title": title,
                    "date": date_time,
                    "source": source,
                    "content": content
                }
            else:
                content_02="".join(item_html.xpath("/html/body/div[3]/form/div[3]/div[1]/div/div/p/text()"))
                edu_info = {
                    "title": title,
                    "date": date_time,
                    "source": source,
                    "content": content_02
                }
            print(edu_info)
        currentPage=currentPage-1
        #print(page_url)
    resp.close();
    

POST请求目标网站

如果通过xpath解析,返回的是空列表,然后通过谷歌浏览器开发者模式,在response的源代码中搜索目标内容,如果没搜到,并且再次发送请求网站没刷新,很大程度上,该页面是通过ajax发出异步请求将返回的数据渲染在页面上的。

  • 实现步骤

    第一步:获取目标网站的url

    第二步:通过requests库发送get请求

    第三步:设置参数用来接收返回的网站

    第四步:通过xpath解析数据

  • 案例分析:

    import requests
    from lxml import etree
    import re
    
    url = "https://www.shxbe.com/front/node/4/nodeData"
    params = {
        'nodeId': 4,
        'pageSize': 9,
        'curPage': 1
    }
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
    }
    resp = requests.post(url, headers=headers, data=params);
    resp.encoding = resp.apparent_encoding
    html = etree.HTML(resp.text);
    if resp.status_code == 200:
        info = resp.json()  # 解析内容为json返回
        current_page = int(info["curPage"])
        pageNum = int(info['totalPage'])
    while current_page <= pageNum:
        page_url = "https://www.shxbe.com/front/node/4/nodeData"
        params = {
            'nodeId': 4,
            'pageSize': 9,
            'curPage': current_page
        }
        _resp = requests.post(page_url, headers=headers, data=params);
        _resp.encoding = _resp.apparent_encoding
        html = etree.HTML(_resp.text);
        if _resp.status_code == 200:
            info = _resp.json()  # 解析内容为json返回
            id_list = info["list"]
            for value in id_list:
                href = "https://www.shxbe.com/front/node/recordInfor/" + str(value['id'])
                resp = requests.get(href, headers=headers);
                resp.encoding = resp.apparent_encoding
                item_html = etree.HTML(resp.text)
                title = "".join(item_html.xpath("/html/body/div[2]/div[2]/h1/text()"))
                source = "".join(item_html.xpath("/html/body/div[2]/div[2]/div[3]/p/i[1]/text()"))
                date = "".join(item_html.xpath("/html/body/div[2]/div[2]/div[1]/div[1]/i/text()"))
                _content = "".join(item_html.xpath("/html/body/div[2]/div[2]/div[2]/p/span/text()"))
                content = re.sub("\s", '', _content);
                if content != "":
                    edu_info = {
                        'title': title,
                        'source': source,
                        'date': date,
                        'content': content
                    }
                    print(edu_info)
        current_page = current_page + 1
    resp.close()
    

几个重要的方法

  • 字符串相关

    方法说明
    “”.join(param1)将param1转字符串
    str(obj)返回一个对象的string格式
    strip()去除首尾空格
  • re相关

    • 正则表达式

      量词 控制前面的元字符出现的次数

      量词说明
      *重复零次或多次
      +重复1次或多次
      重复0次或一次
      {n}重复n次
      .*贪婪匹配
      .*?惰性匹配

      常用元字符

      模式描述
      ^匹配字符串的开头
      $匹配字符串的末尾。
      .匹配换行符以外的任意字符
      […]用来表示一组字符,单独列出:[amk] 匹配 ‘a’,‘m’或’k’
      [^…]不在[]中的字符
      \w匹配字母、数字、下划线
      \s匹配任意空白字符,等价于 [ \t\n\r\f]
      \d匹配任意数字,等价于 [0-9]
    • 方法

      引入re库:import re

      方法名说明举例
      sub(pattern, repl, string, count=0, flags=0)替换字符串中的匹配项content = re.sub("\s", ‘’, _content);替换空白字符
      findall(string[, pos[, endpos]])返回正则表达式所匹配的所有子串 列表source = re.findall(r"文章来源:(.+?) ", _source)

tips

一、伪装成正常访问 审查元素 Networks--Headers---User-Agent
    headers={User-Agent:"  "}
    requests.get(url,headers=headers)
    
二、爬取最后一步   resp.close()

三、数据解析
(1)re解析 正则表达式  re模块
(2)bs4解析
(3)xpath解析
    安装lxml   pip install lxml
    匹配规则:
        /表示层级关系,第一个/是根节点
        text()取标签内容
        //后代
        *任意的节点,通配符
    页面复杂时,结合浏览器审查元素  copy xpath路径
    
四、请求参数过长,重新封装参数
Network-->Headers-->Query String Parameters (保存在params)
url="https://Www.baidu.com"
params={
  "name":"pinkhub"
}
等价于url="https://www.baidu.com/?name=pinkhub"

安装requests插件  pip install requests
                  换源加速 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
五、注意点
1.如果xpath路径中存在tbody,要删掉tbody
2.发出请求没返回内容
(1)UA伪装
(2)反爬机制
3.乱码问题  windows系统电脑默认是gbk,需添加encoding='utf-8'
4.robots.txt协议 规范爬虫  网址/robots.txt
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:26:19  更:2021-11-09 19:29:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 22:56:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码