知行迭代
导航
首页
最近更改
随机页面
常用
分类目录
Linux命令
Mediawiki常用
电脑技巧
工具
链入页面
相关更改
特殊页面
页面信息
登录
查看“网络爬虫”的源代码
←
网络爬虫
页面
讨论
阅读
查看源代码
查看历史
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:[
[1]
]
您可以查看和复制此页面的源代码。
网络爬虫(web crawler),也叫网络蜘蛛(spider),是一种用来自动抓取Web信息数据的程序或者脚本。搜索引擎和其他一些网站使用网路爬虫更新他们的内容。 ==简介== ==获取页面== 以下是基于[[Python]] 3 编程语言的爬虫。 ===request=== request模块是Python的urllib标准库下的模块,直接使用即可。request模块可以方便获取URL内容。 <syntaxhighlight lang="python"> from urllib.request import urlopen html = urlopen('https://www.baidu.com') print(html.read()) </syntaxhighlight> {{了解更多 |[https://docs.python.org/zh-cn/3/library/urllib.request.html Python文档:标准库urllib - request 用于打开 URL 的可扩展库 ] }} ===requests=== [[requests]]是一个Python第三方HTTP库。该软件的目的是使HTTP请求更简单,更人性化。 可以使用[[pip]]安装requests: pip install requests 使用 Requests 发送网络请求非常简单。如获取某个网页,使用get函数,会返回一个Response对象,我们可以从这个对象中获取所有我们想要的信息。 <syntaxhighlight lang="python"> import requests response = requests.get('https://www.baidu.com') print(response.content) </syntaxhighlight> {{了解更多 | [https://requests.readthedocs.io/zh_CN/latest/ Requests文档] | [https://github.com/psf/requests Requests源代码] }} ==解析提取== ===BeautifulSoup=== [[Beautiful Soup]]是一个Python第三方库,可以用来解析html文档,方便提取需要的数据。 可以使用pip安装: pip install beautifulsoup4 如使用BeautifulSoup提取一个页面标题 <syntaxhighlight lang="python"> from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen('https://www.baidu.com') bs = BeautifulSoup(html.read(), 'html.parser') bs.title </syntaxhighlight> ===XPath=== [[XPath]]即XML路径语言(XML Path Language),一种查询语言,用于在XML中选择节点。在Python中,可以使用[[lxml]]这个第三方库来解析页面,然后通过XPath来选取内容。 可以使用pip安装lxml: pip install lxml 如下简单示例,使用requests获取页面,使用lxml解析并用XPath提取标题文本。 <syntaxhighlight lang="python" > import requests from lxml import etree response = requests.get('https://www.baidu.com') html = etree.HTML(response.content) title = html.xpath('//title//text()') </syntaxhighlight> ===表格提取=== ====Pandas==== 如果只要获取页面中的表格,可以使用[[Pandas]]的<code>read_html()</code>函数,简单方便。可以使用pip安装Pandas: pip install pandas 获取某个网页上所有表格,生成一个由DataFrame对象组成的列表: <syntaxhighlight lang="python"> import pandas as pd dfs = pd.read_html('https://pandas.pydata.org/docs/reference/io.html') </syntaxhighlight> <code>read_html()</code>函数默认使用lxml解析,还可以设置为BeautifulSoup4和html5lib。函数格式<code>pandas.read_html(*args, **kwargs)</code>。可选参数 {{了解更多 |[https://pandas.pydata.org/docs/reference/api/pandas.read_html.html Pandas API:read_html] |[https://pandas.pydata.org/docs/user_guide/io.html#html Pandas 指南:IO工具 - HTML] }} ====BeautifulSoup + Pandas==== ====XPath + Pandas==== ===URL解析=== {| class="wikitable" style="width: 100%; ! 名称 ! 描述 ! 示例 |- | [https://docs.python.org/zh-cn/3/library/urllib.parse.html urllib.parse] | 用于解析 [[URL]],Python标准库,使用时导入即可。<br \><syntaxhighlight lang="python"> from urllib import parse </syntaxhighlight> <br \>常用函数:<br \><code>urlparse()</code> 将URL字符串分割成其组成部分。<br \><code>quote()</code> URL编码。 <br \><code>unquote()</code> URL解码。 | <syntaxhighlight lang="python"> parse.unquote('https://example.com/%E9%A6%96%E9%A1%B5') </syntaxhighlight>输出<nowiki>'https://example.com/首页'</nowiki> |- | | | |} ==数据存储== ===二进制文件=== 简单方便,数据不经过解码编码处理,直接将二进制格式保存为文件。一般用于图片,音频,视频,或响应的原文件等。下面使用[[Python]]语言保存图片: <syntaxhighlight lang="python"> import requests import os res = requests.get('http://img0.bdstatic.com/static/searchresult/img/logo-2X_32a8193.png') with open('download.png', 'wb') as f: # 'wb'表示以二进制格式打开文件用于写入 f.write(res.content) # res.content为响应的二进制格式内容 print("图片保存完成。") </syntaxhighlight> 实际存储中,可以进一步完善,如保存过的文件不再下载,文件名与网页中相同。示例如下: <syntaxhighlight lang="python"> import os import requests def download_file(url, save_path,headers=None): save_path = os.path.expanduser(save_path) file_name = url.split('/')[-1] file_path = os.path.join(save_path, file_name) #直接加号拼接需注意:windows使用\和liunxs使用/分割路径。 if not os.path.exists(save_path): #判断是否已存在下载目录 os.makedirs(save_path) #新建下载目录 if not os.path.exists(file_path): #判断是否已存在 res = requests.get(url,headers=headers) with open(file_path, 'wb') as f: # 'wb'表示以二进制格式打开文件用于写入 f.write(res.content) # res.content为响应的二进制格式内容 print("{}文件保存完成。".format(file_path)) else: print("文件已存在。") download_file('http://img0.bdstatic.com/static/searchresult/img/logo-2X_32a8193.png', '~/图片保存目录') </syntaxhighlight> [[Python]]读写文件主要使用open()函数,该函数返回一个文件对象(file object),如果执行失败会抛出OSError。文件对象共有3种类别:原始二进制文件, 缓冲二进制文件,文本文件。 函数<code>open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)</code>最常用的是file和modec参数。如`file_test = open('test.txt', 'r')`表示以只读文本模式创建文件对象,存储在file_test变量中。参数mode是一个可选字符串,用于指定打开文件的模式,默认值是 'r' 。文件对象格式默认为文本模式('t'),可以指定二进制模式('b'),可用的模式有: {| class="wikitable" ! 模式 ! 描述 ! 文件不存在 ! 文件的指针位置 ! 写操作下原文件内容 |- | r | 只读 | 抛出FileNotFoundError | 文件的开头 | 不能写 |- | rb | 二进制模式只读 | 抛出FileNotFoundError | 文件的开头 | 不能写 |- | r+ | 读写 | 抛出FileNotFoundError | 文件的开头 | 清空内容 |- | rb+ | 二进制模式读写 | 抛出FileNotFoundError | 文件的开头 | 清空内容 |- | w | 只写 | 创建文件 | 文件的开头 | 清空内容 |- | wb | 二进制模式只写 | 创建文件 | 文件的开头 | 清空内容 |- | w+ | 读写 | 创建文件 | 文件的开头 | 清空内容 |- | wb+ | 二进制模式读写 | 创建文件 | 文件的开头 | 清空内容 |- | a | 只写追加 | 创建文件 | 文件结尾 | 不变 |- | ab | 二进制模式只写追加 | 创建文件 | 文件结尾 | 不变 |- | a+ | 读写追加 | 创建文件 | 文件结尾 | 不变 |- | ab+ | 二进制模式读写追加 | 创建文件 | 文件结尾 | 不变 |} 注: * r+, rb+ 模式下,如果文件对象先调用read()再调用write(),等同与追加模式 * FileNotFoundError为OSError的子类 在处理文件对象时,最好使用 with 关键字。能够在结束时自动关闭文件对象,不需要自己调用文件对象的close()函数。 {{了解更多 |[https://docs.python.org/zh-cn/3/tutorial/inputoutput.html#reading-and-writing-files Python文档:读写文件] |[https://docs.python.org/zh-cn/3/library/functions.html#open Python文档:内置函数-open()] |[https://docs.python.org/zh-cn/3/glossary.html#term-file-object Python文档:术语对照表-文件对象] }} ===纯文本文件=== 纯文本文件也简单方便,不用转为其他数据格式,直接存储即可。如: <syntaxhighlight lang="python"> # 保存文本 with open('test.txt', 'w') as f: data = 'txt data' f.write(data) print("保存完成") # 读取文本 with open('test.txt', 'r') as f: data = f.read() print(data) </syntaxhighlight> ===CSV文件=== [[CSV]] (Comma Separated Vaules) 格式是电子表格和数据库中最常见的输入、输出文件格式。csv格式一般为:一行一条记录,记录间不同字段值用逗号分隔。如 code, open, high, low, close, apple, 12, 16, 11.2, 14, pear, 12.5, 15, 12.5, 13.5 在python中处理csv格式可以使用标准库csv,直接导入即可。方便用户进行列表或字典格式与csv格式转化。 csv文件的读取,使用csv.reader()或csv.DictReader()函数,函数会生成一个Reader对象。csv.reader()读取的每行以列表形式保存在可迭代对象Reader中;csv.DictReader()生成的Reader对象,每行为字典格式(python 3.8开始)。 csv文件的写入,使用csv.writer()或csv.DictWriter()函数,函数会生成一个Writer对象。Writer对象有2个写入函数:writerow()函数,用于写入单行;writerows(rows)函数,用于写入多行。 <syntaxhighlight lang="python"> import csv # 列表数据,写入csv文件 head_row = ['code', 'open', 'high', 'low', 'close',] rows = [['apple',12, 16, 11.2, 14], ['pear', 12.5, 15, 12.5, 13.5], ] with open('test.csv','w', newline='') as f: csv_writer = csv.writer(f) #生成一个Writer对象 csv_writer.writerow(head_row) #writerow写入单行 csv_writer.writerows(rows) #writerows写入多行 print('test.csv 保存完成 \n') # 字典数据,写入csv文件 fieldnames = ['first_name', 'last_name'] row = {'first_name': 'Baked', 'last_name': 'Beans'} rows = [{'first_name': 'Lovely', 'last_name': 'Spam'}, {'first_name': 'Wonderful', 'last_name': 'Spam'}, ] with open('test.csv', 'w', newline='') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() writer.writerow(row) writer.writerows(rows) print('test.csv 保存完成 \n') # 直接读取文本 with open('test.csv') as f: data = f.read() print('test.csv直接读取文本内容如下:') print(data) # 读取csv文件 with open('test.csv','r', ) as f: rows = csv.reader(f) print('读取csv每行到列表:') for row in rows: print(row) </syntaxhighlight> CSV文件的存储读取,也可以使用其他软件,如[[Pandas]]。 {{了解更多 |[https://docs.python.org/zh-cn/dev/library/csv.html Python文档:标准库csv]}} ===JSON文件=== [[JSON]] (JavaScript Object Notation) 是一种流行的数据交换格式。 JSON数据类型有:字符串(string)、数值(number)、true、false、 null、无序的键值对集合(object)或者有序的列表(array)。因为都是常见的数据结构,使得JSON格式数据可以在编程语言之间进行交换数据。object和array的值可以嵌套,这两种数据类型描述如下: * 无序的键值对集合(object):使用<code>{ }</code>表示,键与值之间用<code>:</code>分隔,键值对之间使用<code>,</code>分割。如{‘name’:‘a’, ‘age’:12} * 有序的列表(array):使用<code>[ ]</code>表示,值之间用<code>,</code>分隔。如[‘a’, 12] 下面一个json格式数据: <pre>{ "Image": { "Width": 800, "Height": 600, "Title": "View from 15th Floor", "Thumbnail": { "Url": "http://www.example.com/image/481989943", "Height": 125, "Width": 100 }, "Animated": false, "IDs": [116, 943, 234, 38793] } }</pre> Python中处理JSON格式可以使用标准库json。json编码器和解码器默认如下转化: {| class="wikitable" ! JSON数据类型 ! 描述 ! 转为python数据类型 ! 由python数据类型转入 |- | string | 字符串,用双引号括起来 | str | str |- | number | 数值 | int或float | int, float, int 和 float 派生的枚举 |- | true | 布尔值 true | True | True |- | false | 布尔值 false | False | False |- | null | 空值 | None | None |- | object | 无序的键值对集合 | dict | dict |- | array | 有序列表 | list | list, tuple |} json常用两个函数:dumps()将python数据类型编码为json格式字符串,loads()将json格式字符串解码为python数据类型。对于从文件读写json格式数据,可以使用dump()和load()函数,会自动转换格式。 <syntaxhighlight lang="python"> import json data = {"name":"image", 'Height':800,'Animated':False} # 格式转换 json_data = json.dumps(data) #转为json格式字符串 print(type(json_data), json_data) data = json.loads(json_data) #转为python数据类型 print(type(data),data) # 读取保存数据,并自动转换相应格式 with open('test.txt', 'r+') as f: json.dump(data, f) #转化为json格式文本对象,并写入文件 print("保存完成") with open('test.txt', 'r+') as f: data = json.load(f) #从文件读取json格式,并转化为python数据类型 print(type(data),data) </syntaxhighlight> {{了解更多 |[https://docs.python.org/zh-cn/dev/tutorial/inputoutput.html#saving-structured-data-with-json Python文档:输入输出-使用 json 保存结构化数据] |[https://docs.python.org/zh-cn/dev/library/json.html#module-json Python文档:标准库json] |[https://www.json.org/json-zh.html JSON官网] }} ===关系型数据库=== 常用关系型数据库[[SQLite]],[[Mysql]],[[PostgreSQL]]等。 [[SQLite]]使用简单,不需要安装配置,一个数据库就是一个文件。[[Python]]中可以使用标准库sqlite3来操作。先创建一个 Connection 对象,它代表数据库。再调用Connection对象的cursor()方法创建一个 Cursor 游标对象。然后调用 Cursor对象的 execute() 方法来执行 SQL 语句。也可以使用[[Pandas]]软件来操作。 SQLite一共5种数据类型,如下: {| ! SQLite类型 ! 描述 ! 从Python类型转入 ! 默认转换为Python类型 |- | NULL | 空值 | None | None |- | INTEGER | 整数,根据值的大小存储,最大8字节,即最大2^63-1=9223372036854775807。 | int | int |- | REAL | 浮点数, 存储为 8 字节的 IEEE 浮点数字。 | float | float |- | TEXT | 文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。 | str | 取决于 text_factory , 默认为 str |- | BLOB | 二进制值,直接存储,不经过转换,如存储图片等。 | bytes | bytes |} 下面使用Python的标准库sqlite3操作示例: <syntaxhighlight lang="python"> import sqlite3 # 生成Connection 对象,它代表数据库。没有会创建一个。 conn = sqlite3.connect('test.db') # 生成Cursor对象 cur = conn.cursor() # 查询是否存在product表 sql = "SELECT count(*) FROM sqlite_master WHERE type='table' AND name='product';" result = cur.execute(sql) #调用execute函数执行sql语句 has_table = result.fetchone() #调用一次fetchone()函数,获取查询结果集的下一行 if has_table[0]: # 查询结果的每一行为元组, print('已存在product表。') else: # sql语句 sql = '''CREATE TABLE product (id INTEGER PRIMARY KEY AUTOINCREMENT , product_id INTEGER NOT NULL, product_name TEXT, supplier_id INTEGER NOT NULL, price REAL, qty real, create_time TimeStamp NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 当前当地时间,以text数据类型保存 create_time2 TimeStamp NOT NULL DEFAULT (datetime('now','localtime')), -- 以text数据类型保存 create_time3 TimeStamp NOT NULL DEFAULT (datetime('now','utc')) -- 以text数据类型保存 )''' # 调用execute函数执行sql语句, 创建product表 cur.execute(sql) print('product表创建成功。') # 插入单行所有字段数据 cur.execute("INSERT INTO product VALUES (5, 37932,'apple','2812', 6.5, '545', 15, 2020,2)") # 插入单行部分字段数据 sql = '''INSERT INTO product (product_id,product_name,supplier_id,price,qty) VALUES (37932,'apple','2812', 6.5, 120);''' cur.execute(sql) conn.commit() conn.close() # 查询product表所有内容 conn = sqlite3.connect('test.db') cur = conn.cursor() result = cur.execute("SELECT * FROM product") print("produc表内容如下:") for row in result.fetchall(): print(row) #删除表 cur.execute("DROP TABLE product") conn.commit() conn.close() print("已删除product表") </syntaxhighlight> {{了解更多 |[https://docs.python.org/zh-cn/3/library/sqlite3.html Python文档:标准库 sqlite3] |[https://docs.python.org/zh-cn/3/library/sqlite3.html#sqlite-and-python-types python文档:标准库 sqlite3-SQLite 与 Python 类型] |[https://www.sqlite.org/datatype3.html SQLite文档:SQLite 3 数据类型] }} ==爬虫进阶== ==法律与道德== ==资源== ==参考资料== *[https://zh.wikipedia.org/wiki/网络爬虫 维基百科:网络爬虫] *[https://zh.wikipedia.org/wiki/网页抓取 维基百科:网页抓取] *[https://en.wikipedia.org/wiki/Web_crawler 维基百科:Web crawler] *[https://en.wikipedia.org/wiki/XPath 维基百科:XPath] [[分类:数据分析]]
本页使用的模板:
模板:了解更多
(
查看源代码
)
返回至“
网络爬虫
”。