首页 > 其他分享 >第十周:网络爬虫和信息提取

第十周:网络爬虫和信息提取

时间:2024-10-31 19:21:19浏览次数:6  
标签:第十 标签 爬虫 信息提取 soup HTML append ltd singleUniv

第十周:网络爬虫和信息提取

1.简介

网络爬虫,Web Spider 或 Web Crawler,是一种自动访问 Web 页面提交数据的自动化程序

网络爬虫应用可以采用 Requests 和 Beautiful Soup 库

Sitemap: https://pypi.org/sitemap.xml
网站地图: https://pypi.org/sitemap.xml
User-agent: *
Disallow: /simple/
Disallow: /packages/
Disallow: /_includes/
Disallow: /pypi/*/json
Disallow: /pypi/*/*/json
Disallow: /pypi*?
Disallow: /search*

用户代理: *
不允许:/simple/
不允许:/packages/
不允许:/_includes/
不允许:/pypi/*/json
不允许:/pypi/*/*/json
不允许:/pypi*?
禁止:/search*

2.Request 库

Request 库是一个简洁且简单的处理 HTTP 请求的第三方库

Request 库总体根据 HTTP 协议处理方式设计其功能函数

HTTP:万维网访问的基本协议

Request 库的网页请求函数:

函数

描述

get(url [, timeout=n])

对应于 HTTP 的 GET 方式,是获取网页最常用的方法,可以增强 timeout=n 参数,设定每次请求时间为 n 秒

post(url, data = {'key':'value'})

对应于 HTTP 的 POST 方式,其中,字典用于传递客户数据

delete(url)

对应 HTTP 的 DELETE 方式

head(url)

对应 HTTP 的 HEAD 方式

options(url)

对应 HTTP 的 OPTIONS 方式

put(url, data = {'key':'value'})

对应 HTTP 的 PUT 方式,其中,字典用于传递客户数据

Request 库的 get()函数用于访问网页,返回内容保存为 Request 对象

import request
r = request.get("http://www.baidu.com")#使用get方法打开百度链接
type(r)#返回Response对象
<class 'requests.models.Response'>

Request 对象的属性

属性

描述

status_code

HTTP 请求的返回状态,整数,200 表示链接成功,404 表示失败

text

HTTP 响应内容的字符串形式,即 url 对应的页面内容

encoding

HTTP 响应内容的编码形式

content

HTTP 响应内容的二进制形式

>>>import requests
>>>r = requests.get("heep://www.baidu.com")
>>>r.status_code#返回状态
200
>>>r.text#观察返回的内容,中文字符是否能正常显示
...
>>>r.encoding#默认编码方式不对,所以中文为乱码
'ISO-8859-1'
>>>r.encoding = 'utf-8'#更改编码方式
>>>r.text#更改成功后,中文即可正常显示

Request 对象的方法

方法

描述

json()

如果 HTTP 响应内容包含 JSON 格式数据,则该解析 JSON 数据

raise_for_status()

如果不是 200,则产生异常 [ 之后就可以用 try-except 捕获异常 ]

受限于网络条件,使用 Request 库功能可能会触发异常:ConnectionError HTTPError Timeout……

import requests
def getHTMLText(url):
    try:
        r = requests.get(url,timeout=30)#url是地址,timeout为请求超时时间
        r.raise_for_status()#如果状态不是200,引发异常
        r.encoding='utf-8'
        return r.text
    except:
        return ""
url = "http://www.baidu.com"
print(getHTMLText(url))

扩展(HTTP 的 GET 和 POST):

定义了客户端与服务器交互的不同方法,一般而言,GET 可以根据某链接获得内容,POST 用于发送内容。然而,GET 也可以向链接提交内容,区别如下:

  1. GET 方式可以通过 URL 提交数据,待提交数据是 URL 的一部分;采用 POST 方式。待提交数据放置在 HTML HEADER 内
  2. GET 方式提交的数据最多不超过 1024 字节,POST 没有对提交内容的长度限制
  3. 安全性问题。使用 GET 时参数会显示在 URL 中,而 POST 不会。所以,如果这些数据是非敏感数据,那么使用 GET;如果提交数据是敏感数据,建议采用 POST 方式

3.实例十七:关键词搜索爬虫

向搜索引擎自动提交关键词并查询,是个技术活

<div ... data-tools= '{"title":"...","url":"..."}'>...</div>
'''
利用beautifulsoup4库找到data-tools属性值,提取带有title的字符串
data-tool内部由{}形成的数据是典型的JSON格式,可用json库将其转换为字典
'''

扩展(CAPTCHA 验证码):

"全自动区分计算机和人类的图灵测试"

4.HTML 标识和 Web 页面

HTML(hypertext markup language)是超文本标记语言,它是专门为 Web 页面组织内容而创建的语言

HTML 语言本质上是键值对的标识,采用<key>value</key>方式表达键 key 对应的值 value

<!DOCTYPE HTML>
<html>
<body>
<meta charset=gb2312>
<h2 align=center>2024 年 1 月部分大中城市新建商品住宅销售价格指数 </h2>
<table border='1' align="center" width=70%>
<tr bgcolor='orange'>
 <th width="40%">城市</th>
<th width="30%">环比</th>
<th width="30%">同比</th>
</tr>
<tr><td align="center">北京</td><td align="center">99.9</td><td align="center">101.3</td></tr>
<tr><td align="center">上海</td><td align="center">100.4</td><td align="center">104.2</td></tr>
<tr><td align="center">广州</td><td align="center">99.2</td><td align="center">96.4</td></tr>
<tr><td align="center">深圳</td><td align="center">99.3</td><td align="center">95.9</td></tr>
<tr><td align="center">沈阳</td><td align="center">99.4</td><td align="center">98.6</td></tr>
</table>
</body>
</html>

解释:HTML 语法中,由<table>表格内容</table>形成的是一个表格,<tr>表格的一行</tr>表示表格的一行。<tr>标签中<th>表头列</th>表示表格表头的一列;<td>内容列</td>表示表格行中的一列。

扩展(Web 前端开发):

Web 前端指开发基于 HTML 的展示效果,经历静态网页制作、动态网页制作和 Web2.0 开发等几个阶段。开发语言主要是 HTML5、CSS、JavaScript

#CSV2HTML.py
seg1 = '''
<!DOCTYPE HTML>\n<html>\n<body>\n<meta charset=gb2312>
<h2 align=center>2024 年 1 月部分大中城市新建商品住宅销售价格指数 </h2>
<table border='1' align="center" width=70%>
<tr bgcolor='orange'>\n '''
seg2 = "</tr>\n"
seg3 = "</table>\n</body>\n</html>"

def fill_data(locls):
    seg = '<tr><td align="center">{}</td><td align="center">' + \
        '{}</td><td align="center">{}</td></tr>\n'
    seg = seg.format(*locls)
    return seg

with open("price202401.csv", encoding='utf-8') as fr:
    ls = []#将CSV文件读入列表ls
    for line in fr:
        line = line.replace("\n","")#格式化字符串方法将ls中内容写入HMTL文件
        ls.append(line.split(","))

with open("price202401.html", "w",encoding='utf-8') as fw:
    fw.write(seg1)
    seg = '<th width="40%">{}</th>\n<th width="30%">{}</th>\n'+\
        '<th width="30%">{}</th>\n'
    fw.write(seg.format(*ls[0]))
    fw.write(seg2)
    for i in range(len(ls)-1):
        fw.write(fill_data(ls[i+1]))
    fw.write(seg3)

#限于技术有限,我的编码不太对

5.HTML 语言概述

  1. 标签(Tags) :HTML文档由各种标签组成,每个标签用于定义文档的不同部分。标签通常成对出现,包括开始标签和结束标签。例如,<p></p>分别表示段落的开始和结束。有些标签是自闭合的,如<br><img>,它们不需要结束标签。
  2. 元素(Elements) :元素是由开始标签、内容和结束标签组成的整体。例如,<p>这是一个段落。</p>就是一个元素,其中<p>是开始标签,</p>是结束标签,中间的内容是元素的内容。
  3. 属性(Attributes) :属性提供了关于元素的额外信息。属性通常出现在开始标签内,格式为属性名="属性值"。例如,<a href="[http://www.example.com](http://www.example.com) ">这是一个链接</a>中的href是一个属性,指定了链接的目标地址。
  4. 注释(Comments) :注释用于在HTML代码中添加说明,不会被浏览器解析。注释的格式是<!-- 这是一个注释 -->
  5. 文档类型声明(DOCTYPE) :文档类型声明是HTML文档的第一行,用于告诉浏览器文档使用的HTML版本。例如,<!DOCTYPE html>声明这是一个HTML5文档。
  6. 基本结构:一个标准的HTML文档通常包含以下几个部分:
    • <!DOCTYPE html>:文档类型声明。
    • <html>:HTML文档的根元素。
    • <head>:包含文档的元数据,如标题、字符集等。
    • <title>:定义文档的标题,显示在浏览器的标题栏或标签页上。
    • <body>:包含文档的实际内容,如文本、图像、链接等。
  1. 特殊字符和实体(Entities) :HTML中有一些特殊字符需要使用实体来表示,例如<表示小于号<>表示大于号>
  2. 嵌套和层次结构:HTML元素可以嵌套,形成层次结构。例如,一个段落可以包含多个句子,每个句子可以包含单词和标点符号。
  3. 大小写不敏感:HTML标签和属性名不区分大小写,例如<p><P>是相同的。

通过这些基本语法形式,可以构建出复杂的网页结构和内容。

6.Beautiful Soup 库

Beautiful Soup 库能够用来解析 HTML 和 XML 的第三方库,也称 beautifulsoup4 或 bs4

使用 Request 库获取 HTML 页面并将其转换成字符串后,需要进一步解析 HTML 页面格式,提取有效信息,这需要处理 HTML 和 XML 的函数库

pip install -U beautifulsoup4

from bs4 import BeautifulSoup从库中引入 BeautifulSoup 类

Beautiful Soup库采用 BeautifulSoup 对象表示一个页面

import requests
from bs4 import BeautifulSoup
r = requests.get("http://www.baidu.com")
r.encoding = 'utf-8'
soup = BeautifulSoup(r.text)
type(soup)
'''
<class 'bs4.BeautifulSoup'>
'''
soup.head
'''
<head><meta content="text/html;charset=utf-8" http-equiv="content-type"/><meta content="IE=Edge" http-equiv="X-UA-Compatible"/><meta content="always" name="referrer"/><link href="http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css" rel="stylesheet" type="text/css"/><title>百度一下,你就知道</title></head>
'''
title=soup.title
type(title)
'''
class 'bs4.element.Tag'>
'''
soup.p
'''
<p id="lh"> <a href="http://home.baidu.com">关于百度</a> <a href="http://ir.baidu.com">About Baidu</a> </p>
'''

BeautifulSoup 对象的常用属性

属性

描述

head

HTML 页面的<head>内容

title

HTML 页面标题,在<head>之中,由<title>标记

body

HTML 页面的<body>内容

p

HTML 页面中第一个<p>内容

strings

HTML 页面所有呈现在 Web 上的字符串,即标签的内容

stripped_strings

HTML 页面所有呈现在 Web 上的非空格字符串

<a class="mnav" href="http://www.nuomi.com">糯米</a>
'''
<>中的是标签的名字name,其他项是sttrs,尖括号间的内容是string
'''
>>>soup.a
<a class="mnav" herf="http://www.nuomi.com">糯米</a>
>>>soup.a.name
'a'
>>>soup.a.attrs
{'href':'http://www.nuomi.com','class':['mnav']}
>>>soup.a.string
'糯米'
>>>title.name#title变量在上段例子中已经定义
'title'
>>>title.string
'百度一下,你就知道'
>>>soup.p.contents
……

标签对象的常用属性:

属性

描述

name

字符串,标签的名字,比如 div

attrs

字典,包含了原来页面 Tag 所有的属性,比如 href

contents

列表,这个 Tag 下所以子 Tag 的内容

string

字符串,Tag 所包围的文本,网页中真实的文字

String 属性的返回遵循如下原则:

  1. 如果标签内部没有其他标签,string 属性返回其中的内容
  2. 如果标签内部还有其他标签,但只有一个标签,string 属性返回最里面标签的内容
  3. 如果标签内部有超过 1 层嵌套的标签,string 属性返回 None(空字符串)

按照条件返回标签内容:

BeautifulSoup.find_all(name,attrs,recursive,string,limit)

name:按照 Tag 标签名字检索,名字用字符串形式表示,例如,div、li。

sttrs:按照 tag 标签属性值检索,需要列出属性名称和值,采用 JSON 表示

recursive:设置查找层次,只查找当前标签下一层时使用 recursive=False

string:按照关键字检索 string 属性内容,采用 string=开始

limit:返回结果的个数,默认返回全部结果

正则表达式:

正则表达式(Regular Expression,简称regex或regexp)是一种强大的文本处理工具,用于在字符串中查找、匹配和替换特定的模式。它由普通字符(如字母、数字)和特殊字符(称为元字符)组成,能够描述复杂的字符串匹配规则。正则表达式广泛应用于编程、数据验证、文本处理等领域,是处理字符串的强大武器。

7.实例十八:中国大学排名爬虫

采用网络爬虫技术,从网页上获取中国大学排名数据

allUniv=[]
def fillUnivList(soup):
    data = soup.find_all('tr')
    for tr in data:
        singleUniv = []
        ltd = tr.find_all('td')
        singleUniv.append(ltd[0].string.strip("\n "))
        singleUniv.append(list(ltd[1].strings)[1].strip("\n "))
        singleUniv.append(list(ltd[2].strings)[0].strip("\n "))
        singleUniv.append(list(ltd[3].strings)[0].strip("\n "))
        singleUniv.append(ltd[4].string.strip("\n "))
        allUniv.append(singleUniv)
allUniv=[]#存储全部表格数据,二维列表
def fillUnivList(soup):
    singleUniv = []
    ltd = tr.find_all('td')
    if len(ltd)==0:
        continue
    singleUniv.append(ltd[0].string.strip("\n "))
    singleUniv.append(list(ltd[1].strings)[1].strip("\n "))
    singleUniv.append(list(ltd[2].strings)[0].strip("\n "))
    singleUniv.append(list(ltd[3].strings)[0].strip("\n "))
    singleUniv.append(ltd[4].string.strip("\n "))
    allUniv.append(singleUniv)data = soup.find_all('tr')
#CrawUnivRanking.py
import requests
from bs4 import BeautifulSoup
from prettytable import PrettyTable
allUniv = []

def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = 'utf-8'
        return r.text
    except:
        return ""
 
def fillUnivList(soup):
    data = soup.find_all('tr')
    for tr in data:
        singleUniv = []
        ltd = tr.find_all('td')
        if len(ltd)==0:
            continue
        singleUniv.append(ltd[0].string.strip("\n "))
        singleUniv.append(list(ltd[1].strings)[1].strip("\n "))
        singleUniv.append(list(ltd[2].strings)[0].strip("\n "))
        singleUniv.append(list(ltd[3].strings)[0].strip("\n "))
        singleUniv.append(ltd[4].string.strip("\n "))
        allUniv.append(singleUniv)

def printUnivList(num):
    tb = PrettyTable();
    tb.field_names = [" 排名 "," 学校名称 "," 省市 "," 类型 "," 总分 "]
    for i in range(num):
        tb.add_row(allUniv[i])
    print(tb)
 
def main(num):
    url = 'https://www.shanghairanking.cn/rankings/bcur/2023'
    html = getHTMLText(url)
    soup = BeautifulSoup(html, "html.parser")
    fillUnivList(soup)
    printUnivList(num)
 
main(10)
'''
+--------+------------------+--------+--------+--------+
|  排名  |     学校名称     |  省市  |  类型  |  总分  |
+--------+------------------+--------+--------+--------+
|   1    |     清华大学     |  北京  |  综合  | 1004.1 |
|   2    |     北京大学     |  北京  |  综合  | 910.5  |
|   3    |     浙江大学     |  浙江  |  综合  | 822.9  |
|   4    |   上海交通大学   |  上海  |  综合  | 778.6  |
|   5    |     复旦大学     |  上海  |  综合  | 712.4  |
|   6    |     南京大学     |  江苏  |  综合  | 676.2  |
|   7    | 中国科学技术大学 |  安徽  |  理工  | 608.6  |
|   8    |   华中科技大学   |  湖北  |  综合  | 606.2  |
|   9    |     武汉大学     |  湖北  |  综合  | 599.1  |
|   10   |   西安交通大学   |  陕西  |  综合  | 572.6  |
+--------+------------------+--------+--------+--------+
'''

8.PrettyTable 库与格式化展示

PrettyTable 库是一个在终端生成简洁格式化文本的第三方库

pip install -U prettytable

from prettytable import PrettyTable
table = PrettyTable()
table.field_names = ["City","Area (sq km)","Population"]
table.add_row(["Adelaide",1295,115829])
table.add_row(["Brisbane",5905,1857954])
table.align = "l"
print(table)
'''
+----------+--------------+------------+
| City     | Area (sq km) | Population |
+----------+--------------+------------+
| Adelaide | 1295         | 115829     |
| Brisbane | 5905         | 1857954    |
+----------+--------------+------------+
'''

PrettyTable 库的主要函数:

函数

描述

PrettyTable()

创建一个 PrettyTable 对象

field_names()

设置或获取表格的字段名称,即列的名字

add_row()

向表格中添加一行数据

add_column()

向表格中添加一整列数据

align()

设置指定列的对齐方式,左对齐"I"、居中"c"、右对齐"r"

del_row(row_indes)

删除指定索引的行

clear()

清空表格中的所有行数据

sortby()

设置排序依据的列名

创建表格,增加一行数据:

from prettytable import PrettyTable
table = PrettyTable(["Name","Age","City"])
table.add_row(["Alice",30,"New York"])
print(table)
'''
+-------+-----+----------+
|  Name | Age |   City   |
+-------+-----+----------+
| Alice |  30 | New York |
+-------+-----+----------+

'''

增加新列 Occupation,设置第一行对应该列的值为 Engineer:

table.add_column("Occupation",["Engineer"])
print(table)
'''
+-------+-----+----------+------------+
|  Name | Age |   City   | Occupation |
+-------+-----+----------+------------+
| Alice |  30 | New York |  Engineer  |
+-------+-----+----------+------------+
'''

设置各列对齐方式:

table.align["Name"] = "l"
table.align["Age"] = "c"
table.align["City"] = "r"
print(table)
'''
+-------+-----+----------+------------+
| Name  | Age |     City | Occupation |
+-------+-----+----------+------------+
| Alice |  30 | New York |  Engineer  |
+-------+-----+----------+------------+

'''

增加数据,设置根据年龄排序:

table.add_row(["Charlie",25,"Chicago","Artist"])
table.sortby = "Age"
print(table)
'''
+---------+-----+----------+------------+
| Name    | Age |     City | Occupation |
+---------+-----+----------+------------+
| Charlie |  25 |  Chicago |   Artist   |
| Alice   |  30 | New York |  Engineer  |
+---------+-----+----------+------------+
'''

标签:第十,标签,爬虫,信息提取,soup,HTML,append,ltd,singleUniv
From: https://blog.csdn.net/DA_CK/article/details/143415025

相关文章

  • 爬虫获取主页信息
    爬虫获取主页信息1.如何使Python获取到网页的源代码 urllib:用来模拟浏览器 urllib.request:获取主页源码 urllib.request.Request():构建数据结构 add_header("user-agent"):添加请求头,伪装浏览器 urllib.request.urlopen():打开URL获取源码 2.过滤爬虫爬取主页信息#调用......
  • 练习爬虫的网站
    练习爬虫的网站http://www.glidedsky.com/爬虫-基础1爬虫的目标很简单,就是拿到想要的数据。这里有一个网站,里面有一些数字。把这些数字的总和,输入到答案框里面,即可通过本关。题目其实是蛮简单的,就是抓取一个网页中的数据,然后求和。代码如下:##把这些数字的总和,输入到答......
  • 编写高性能爬虫抓取股票行情数据
    最近给一个私募大佬帮忙做了一些股票交易有关的系统,其中涉及到行情数据抓取的问题,一番摸索之后,把成果在这里做个分享。我把行情抓取的部分,和一个写手记的小功能,单独拿了出来放在一个小系统里面,可以免费使用:https://rich.shengxunwei.com/先简单介绍下这个小系统的样子,然后我会详......
  • 推荐5个开发人员最常用的高级爬虫软件
    爬虫,又称为网络爬虫或网页爬虫,是一种自动浏览互联网的程序,它按照一定的算法顺序访问网页,并从中提取有用信息。爬虫软件通常由以下几部分组成:- 用户代理(User-Agent):模拟浏览器访问,避免被网站识别为机器人。- 请求处理:发送HTTP请求,获取网页内容。- 内容解析:使用正则表达式或......
  • 奥数与C++小学四年级(第十五题 希望数)
    参考程序代码:#include<iostream>#include<vector>usingnamespacestd;//每个数字所需的火柴棍数量vector<int>matchsticks={6,2,5,5,4,5,6,3,7,6};//函数来计算一个数的火柴棍总数和数字和voidcheckHopeNumber(intnumber){inttotalMatchst......
  • Java爬虫:在1688上“夺宝奇兵”获取店铺详情
    想象一下,你是一名勇敢的探险家,手持藏宝图,在数字世界的海洋中寻找那传说中的宝藏——1688店铺详情。今天,我们将一起化身为代码界的“夺宝奇兵”,使用Java爬虫技术,揭开1688店铺详情的神秘面纱。准备好你的帽子和鞭子,我们即将启程!背景介绍你是否曾在浏览1688时,对那些神秘的店铺充......
  • 代码随想录算法训练营第十二天| 226.翻转二叉树、101. 对称二叉树、104.二叉树的最大
    226.翻转二叉树题目链接:.-力扣(LeetCode)文章讲解:代码随想录视频讲解:听说一位巨佬面Google被拒了,因为没写出翻转二叉树|LeetCode:226.翻转二叉树_哔哩哔哩_bilibili《代码随想录》算法公开课开讲啦!快来打卡!本期视频的文字讲解版在「代码随想录」刷题网站:programmercarl.com......
  • 代码随想录算法训练营第十三天| 110.平衡二叉树、257. 二叉树的所有路径、404.左叶子
    110.平衡二叉树题目链接:.-力扣(LeetCode)文章链接:代码随想录视频链接:后序遍历求高度,高度判断是否平衡|LeetCode:110.平衡二叉树_哔哩哔哩_bilibili《代码随想录》算法公开课开讲啦!快来打卡!本期视频的文字讲解版在「代码随想录」刷题网站:programmercarl.com,这里刷题顺序,详......
  • ZZJC新生训练赛第十二场题解
    难度分类(同一难度下按字典序上升)入门:G简单:C,E,A中等:F,D,B困难:HG-解题思路按照题意模拟即可G-代码实现#include<bits/stdc++.h>intmain(){std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);std::strings;......
  • 猿人学web端爬虫攻防大赛赛题第17题——天杀的http2.0
    题目网址:https://match.yuanrenxue.cn/match/17解题步骤:老方法,看触发的数据包。只有一个数据包,再看cookie中有没有特殊的字段。没有遇到第13题的特殊字段,直接访问。importrequestsurl="https://match.yuanrenxue.cn/api/match/17?page=1"headers={"user-ag......