爬虫数据解析

124 阅读4分钟

我正在参加「掘金·启航计划」

爬虫数据解析

  • HTTP是一种无状态的协议,客户端与服务端建立连接并传输数据,数据传输完成后,连接就会关闭;
  • 在次交互数据就必须建立新的连接
  • Cookie是解决HTTP无状态的有效手段,服务器可以设置或读取Cookie中的所包含的信息。
  • Cookie是网站为了辨别用户身份,会话跟踪而储存在用户本地终端上的数据
  • 是由Web服务器创建的,用语识别的“小量信息”,存储在本地浏览器目录中的文本文件。
  • 它用来保存状态信息,是保存客户端状态的机制
  • Session和Cookie一样,也是保存客户端状态的机制

  • 它们最大的不同是,Cookie把客户状态保存在客户端,而Session保存在服务器。

    • 用户使用浏览器访问服务器时,服务器把用户信息以某种形式记录在服务器上。
    • 购物网站的购物车记录就是基于此实现的

image-20220910111019643

  • 源代码(也称源程序)是指未编译的按照一定的程序设计语言规范书写文本文件

    • 计算机源代码的目的是将人类可读的文本翻译成计算机可执行的二进制指令
  • HTML,是Hypertext Markup Language的英文缩写,即超文本标记语言,是制作网页内容的一种标签语言。

    • HTML通过在内容附加各种标签,在浏览器中正确展示内容。

HTLM链接:

HTML图像

  • HTML图像是通过标签来定义的

    <img src= "C:\Users\11265\Desktop\刷题顺序.png" width = "200" height = "100" />

image-20220910124747812

<div>标签

  • 定义HTML文档中的一个分隔区块
  • 标签常用于组合块级元素,以便通过CSS来对这些元素进行格式化

<li>标签

  • 定义列表项目,
  • 标签可用在有序列表(<ol>)和无序列表(<ul>)中

<br>标签

  • 可插入一个简单的换行符

<em>标签

  • 告诉浏览器把其中的文本表示为强调的内容。对于所有浏览器来说,这意味着要把这段文字用斜体来显示。

<cite>标签

  • 定义作品(比如书籍、歌曲、电影、电视节目、绘画、雕塑等等)的标题。

<font标签>

  • 规定文本字体、大小和颜色
  • <font size = "3" color= "red">hi,bro!

简单的HTML表格由table元素以及一个或多个tr、th或td元素组成。

  • <tr>标签定义HTML表格中的行。

  • <\th>和标签都是用于单元格内容显示,但内部文本会加粗。

  • 标签定义HTML表格

  • 标签定义表格标题。caption标签必须紧随table标签之后。

解析HTML页面的源代码工具:

  • 正则表达式
  • lxml
  • BeautifulSoup

正则表达式的语法:

image-20220910131154325

匹配模式:遇到换行符"\n"时,' . '不再能匹配,因此要制定re.S.

import re
content ='hack 123 4 \n is the best'
result =  re.match('^ha.*(\d+).*best',content, re.S)
print(result.group(1))
print(result.string)
  • 总结:尽量使用非贪婪模式、泛匹配、用括号得到匹配目标、换行指定re.S

转义:当遇到"." 、""、 "$"、 "+" 等特殊字符时,需要转义。

import re
​
content ='100.00$'
result = re.match('100.00$',content)
print(result.string)

BeautifulSoup

  • 与正则表达式,lxml相比,BeautifulSoup

    • 提供Python式的函数来处理导航、搜索、修改分析树等功能
    • 自动将输入编码转换为Unicode,输出编码转换为utf-8
    • 为用户提供不同的解析策略
    • 相比正则和Xpath解析,降低学习成本

使用BeatifulSoup的命令

  • from bs4 import BeautifulSoup

DOM树

image-20220910142031605

  • BeautifulSoup库基于DOM,会载入整个HTML文档,并解析整个DOM树。
  • HTML是分层的,由标签、属性、数据组成,这些元素整体构成一棵DOM树。
  • DOM树中每个节点都是一个元素,元素可以有自己的属性,也可以包含若干个子元素。

利用find_all()找到'ul'下的全部标签

print(soup.find_all('ul'))

利用‘for’循环进行嵌套查找

for ul in soup.find_all('ul'):
    print(ul.find_all('li'))

re包相关代码

#re.findall
import re
html ='''<li data-type="xlwb">
<a href="javascript:;" class="logo xlwb"></a>
<a href="javascript:;" class="wd">新浪微博</a>
</li>
<li data-type="wx">
<a href="javascript:;" class="logo wxfrd"></a>
<a href="javascript:;" class="wd">微信</a>
</li>'''
​
results = re.findall('<li.*?href="(.*?)".*?class="wd">(.*?)</a>',html,re.S)
print(results)
#re.sub
import re
​
content ='hack 123 4 is the best'
content = re.sub('\d','',content)
print(content)
#re.compile
import re
​
content ='hack 123 4 is the best'
pattern =re.compile ('hack.*best')
result = re.match(pattern,content)
print(result.string)

BeautifulSoup包代码

#解析微博代码
html='''<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="initial-scale=1,minimum-scale=1" />
<link rel="mask-icon" sizes="any" href="//img.t.sinajs.cn/t6/style/images/apple/wbfont.svg" color="black" />
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<script type="text/javascript">
try{document.execCommand("BackgroundImageCache", false, true);}catch(e){}
</script>
<title>微博-随时随地发现新鲜事</title>
<link href="//img.t.sinajs.cn/t6/style/css/module/base/frame.css?version=2018071909" type="text/css" rel="stylesheet" charset="utf-8" />
from bs4 import BeautifulSoup#通过选择标签很方便地查找内容

soup = BeautifulSoup(html,'xml')#构建一个dom树
print(soup.head)
print(soup.script)
print(soup.link)#返回选择标签的第一个内容

print(soup.prettify())#prettify方法对代码进行格式化
print(soup.title.string)#获得title内容


html='''<div class="more-items">#豆瓣的HTML代码
        <table cellpadding="0" cellspacing="0">
          <tbody>
            <tr>
              <td>
                 'douban'
                <a href="https://read.douban.com/ebooks/?dcs=book-nav&dcm=douban"target="_blank">电子图书</a>
                <a href="https://ypy.douban.com" target="_blank" data-moreurl-dict="{&quot;from&quot;:&quot;top-nav-click-ypy&quot;,&quot;uid&quot;:&quot;0&quot;}">豆瓣摄影</a>
                <a href="https://book.douban.com/cart/">购书单,'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.table.children)#打印table的子节点
for i,children in enumerate(soup.table.children):#遍历每个子节点
    print(i,children)
html='''<div class="nav-items">
  <ul>
    <li id='list-1'><a href="https://book.douban.com/cart/"
     >购书单</a>
    </li>
  </ul>
  <ul>
    <li    ><a href="https://market.douban.com/book?utm_campaign=book_"
     >豆瓣书店</a>
    </li>
    <li    ><a href="https://book.douban.com/annual/2017?source=navigation"
            target="_blank"
     >2017年度榜单</a>
    </li>
    <li          class=" book-cart"
    ><a href="https://market.douban.com/cart"'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')

   

print(soup.find_all('ul'))   
for ul in soup.find_all('ul'):
    print(ul.find_all('li'))#利用’for’循环进行嵌套查找

print(soup.find_all(text='豆瓣书店'))#Text:指定文本来查找

print(soup.find_all(id='list-1'))#attrs:指定标签内的属性来指定查找

print(soup.select('ul li'))#通过标签直接或逐层查找
print(soup.select('.book-cart'))#通过’class’类查找,但要在类前面加点号
print(soup.select('#list-1'))#通过’id’查找,在ID前面加井号键
for a in soup.select('a'):
    print(a['href'])#获取某个标签的属性
for li in soup.select('li'):
    print(li.get_text())#获取文本内容

lxml库

BeautifulSoup与lxml对t比

  • 原理不同 BeautifulSoup基于DOM载入整个文档,对内存消耗大。 lxml用XPath处理HTML和XML文档,局部遍历
  • 操作性 BeautifulSoup操作更加简单,但熟练XPath的话推荐lxml。

lxml库-解析文本

  • 在输出结果中,lxml也像BeautifulSoup的prettify()一样,会补全之前缺失的HTML标签

image-20220910145614323

lxml库-XPath

XPath像正则表达式一样用路径表示节点位置

表达式说明
nodename选择nodename的所有子节点
/从根节点开始
//从匹配选择的当前节点开始选择
//nodename从当前节点nodename开始选择
.选择当前节点
..选择当前节点的父节点
@选择属性

lxml库相关代码

#lxml
from lxml import etree#lxml使用此命令解析文本
html_str = '''<div class="nav-items">
  <ul>
    <li id='list-1'><a href="https://book.douban.com/cart/"
     >购书单</a>
    </li>
  </ul>
  <ul>
    <li    ><a href="https://market.douban.com/book?utm_campaign=book_"
     >豆瓣书店</a>
    </li>
    <li    ><a href="https://book.douban.com/annual/2017?source=navigation"
            target="_blank"
     >2017年度榜单</a>
    </li>
    <li          class=" book-cart"
    ><a href="https://market.douban.com/cart'''
​
​
html = etree.HTML(html_str)#获取该段HTML的所有属性
hrefs = html.xpath('//@class')
#‘//’表示从任意位置开始选取节点
for href in hrefs:
    print(href)
    
    
#html = etree.HTML(html_str)#获取该段HTML所有的a标签下的链接
​
hrefs = html.xpath('//ul/li/a/@href')
for href in hrefs:
    print(href)
import requests
from lxml import etree
header = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"}
response = requests.get(url='https://www.douban.com/',headers = header).text
html = etree.HTML(response)
hrefs = html.xpath('//*[@id="anony-time"]/div/div[3]/ul/li[1]/a[2]/text()')#获取审查元素的Xpath路径
print(hrefs)