requests库方法
pip install requests
方法 | 说明 |
---|---|
requests.request() | 构造一个请求,支撑以下各种方法 |
requests.get() | 获取HTML网页的主要方法,对应于HTTP的GET |
requests.head() | 获取HTML网页头信息的方法,对应于HTTP的HEAD |
requests.post() | 向HTML网页提交POST请求的方法,对应于HTTP的POST |
requests.put() | 向HTML网页提交PUT请求的方法,对应于HTTP的PUT |
requests.patch() | 向HTML网页提交局部修改请求,对应于HTTP的PATCH |
requests.delete() | 向HTML网页提交删除请求,对应于HTTP的DELETE |
Requests库的get方法
r = requests.get(url)
构造一个向服务器请求资源的Request对象
返回一个包含服务器资源的Response对象,包含爬虫返回的全部内容
完整使用方法:
requests.get(url, params=None, **kwargs)
url:拟获取页面的url链接
params:url中的额外参数,字典或字节流格式,可选
kwargs:12个控制访问的参数
Response对象的属性
属性 | 说明 |
---|---|
r.status_code | HTTP请求的返回状态,200表示连接成功 |
r.text | HTTP响应内容的字符串形式,即url对应的页面内容 |
r.encoding | 从HTTP header中猜测的相应内容编码方式 |
r.apparent_encoding | 从内容分析出的响应内容编码方式(备选编码方式) |
r.content | HTTP相应内容的二进制形式 |
Requests库的异常
异常 | 说明 |
---|---|
requests.ConnectionError | 网络连接错误异常,如DNS查询失败、拒绝连接等 |
requests.HTTPError | HTTP错误异常 |
requests.URLRequired | URL缺失异常 |
requests.TooManyRedirects | 超过最大重定向次数,产生重定向异常 |
requests.ConnectTimeout | 连接远程服务器超时异常 |
requests.Timeout | 请求URL超时,产生超时异常 |
r.raise_for_status()
如果不是200,产生异常requests.HTTPError
抓取网页的通用代码框架
import requests
def getHTMLText(url):
try:
r = requests.get(rul, timeout=30)
r.raise_for_status() #如果状态不是200,引发HTTPError异常
r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常"
HTTP协议
url格式 http://host[:port][path]
host:合法的Internet主机域名或IP地址
port:端口号,缺省端口为80
path:请求资源的路径
HTTP协议对资源的操作
方法 | 说明 |
---|---|
GET | 请求获取URL位置的资源 |
HEAD | 请求获取URL位置资源的响应消息报告,即获得该资源的头部信息 |
POST | 请求向URL位置的资源后附加新的数据 |
PUT | 请求向URL位置存储一个资源,覆盖原URL位置的资源 |
PATCH | 请求局部更新URL位置的资源,即改变该处资源的部分内容 |
DELETE | 请i去删除URL位置存储的资源 |
HTTP协议与Requests库
HTTP协议 | Requests库方法 | 功能一致性 |
---|---|---|
GET | requests.get() | 一致 |
HEAD | requests.head() | 一致 |
POST | requests.post() | 一致 |
PUT | requests.put() | 一致 |
PATCH | requests.patch() | 一致 |
DELETE | requests.delete() | 一致 |
Requests库的head()方法
r = requests.head('http://httpbin.org/get')
r.headers
r.text
Requests库的post()方法
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.post('http://httpbin.org/post', data = payload)
print(r.text)
# 向URL POST一个字典,自动编码为form(表单)
r = requests.post('http://httpbin.org/post', data = 'ABC')
print(r.text)
# 向URL POST一个字符串,自动编码为data
Requests库的put()方法
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.put('http://httpbin.org/put', data = payload)
print(r.text)
Requests库主要方法解析
requests.request(method, url, **kwargs)
method:请求方式,对应get/put/post等7种
url:拟获取页面的url链接
**kwargs:控制访问的参数,共13个
methond:请求方式
requests.request('GET', url, **kwargs)
requests.request('HEAD', url, **kwargs)
requests.request('POST', url, **kwargs)
requests.request('PUT', url, **kwargs)
requests.request('PATCH', url, **kwargs)
requests.request('delete', url, **kwargs)
requests.request('OPTIONS', url, **kwargs)
**kwargs:控制访问参数,均为可选项
params:字典或字节序列,作为参数增加到url中
data:字典字节序列或文件对象,作为Request的内容
json:JSON格式的数据,作为Request的内容
headers:字典,HTTP定制头
cookies:字典或CookieJar,Request中的cookie
auth:元祖,支持HTTP认证功能
files:字典类型,传输文件
timeout:设定超时时间,秒为单位
proxies:字典类型,设定访问代理服务器,可以增加登陆认证
allow_redirects:True/False,默认为True,重定向开关
stream:True/False,默认为True,获取内容立即下载开关
verify:True/False,默认为True,认证SSL证书开关
cert:本地SSL证书路径
其它6个主要函数
requests.get(rul, params = None, **kwargs)
url:拟获取页面的url链接
params:url中的额外参数,字典或字节流格式,可选
**kwargs:12个控制访问参数
requests.head(url, **kwargs)
url:拟获取页面的url连接
**kwargs:13个控制访问的参数
requests.post(url, data=None, json=None, **kwargs)
url:拟更新页面的url链接
data:字典、字节序列或文件,Request的内容
json:JSON格式的数据,Request的内容
**kwargs:11个控制访问的参数
requests.put(url, data=None, **kwargs)
url:拟更新页面的rul链接
data:字典、字节序列或文章,Request的内容
**kwargs:12个控制访问参数
requests.patch(url, data=None, **kwargs)
url:拟更新页面的url链接
data:字典、字节序列或文件,Request的内容
**kwargs:12个控制访问的参数
requests.delete(url, **kwargs)
url:拟删除页面的url链接
**kwargs:13个控制访问的参数
Robots协议
Robots Exclusion Standard 网络爬虫排除标准
# 注释,*代表所有,/代表目录
作用:网站告知网络爬虫哪些页面可以抓取,哪些不行
形式:在网站根目录下的robots.txt文件
Robots协议的使用
网络爬虫:自动或人工识别robots.txt,再进行内容爬取
约束性:Robots协议是建议但非约束性,网络爬虫可以不遵守,但存在法律风险
实例1:京东商品页面的爬取
import requests
url = "http://item.jd.com/2967929.html"
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = r.apparent_encoding
print(r.text)
except:
print("爬取失败")
实例2:亚马逊商品页面爬取
import requests
url = "https://www.amazon.cn/gp/product/B01M8L5Z3Y"
try:
kv = {'user-agent':'Mozilla/5.0'}
r = requests.get(url, headers=kv)
r.raise_for_status()
r.encoding = r.apparent_encoding
print(r.text)
except:
print("爬取失败")
实例3:百度/360搜索关键词提交
搜索关键词接口
百度的关键词接口:http://www.baidu.com/s?wd=keyword
360的关键词接口:http://www.so.com/s?q=keyword
import requests
keyword = "Python"
try:
kv = {'wd':keyword}
r = requests.get("http://www.baidu.com/s",params=kv)
print(r.request.url)
r.raise_for_status()
print(len(r.text))
except:
print("爬取失败")
实例4:网络图片的爬取和存储
网络图片链接的格式:http://www.example.com/picture.jpg
import requests
import os
url = "http://image.nationalgeographic.com.cn/2017/0211/20170211061910157.jpg"
root = "G:/Code/python/mooc爬虫/"
path = root + url.split('/')[-1]
try:
if not os.path.exists(root):
os.mkdir(root)
if not os.path.exists(path):
r = requests.get(url)
with open(path, 'wb') as f:
f.write(r.content)
print("文件保存成功")
else:
print("文件已存在")
except:
print("爬取失败")
实例5:IP地址归属地自动查询
import requests
url = "http://m.ip138.com/ip.asp?ip="
try:
r = requests.get(url+'202.204.80.112')
r.raise_for_status()
r.encoding = r.apparent_encoding
print(r.text)
except:
print("爬取失败")
Beautiful Soup 库
Beautiful Soup 库是解析、遍历、维护“标签树”的功能库
pip install beautifulsoup4
Beautiful Soup 库的引用
from bs4 import BeautifulSoup
Beautiful Soup 库解析器
解析器 | 使用方法 | 条件 |
---|---|---|
bs4的HTML解析器 | BeautifulSoup(mk,'html.parser') | 安装bs4库 |
xlml的HTML解析器 | BeautifulSoup(mk,'lxml') | pip install lxml |
lxml的XML解析器 | BeautifulSoup(mk,'xml') | pip install lxml |
html5lib的解析器 | BeautifulSoup(mk,'html5lib') | pip install html5lib |
Beautiful Soup 类的基本元素
基本元素 | 说明 |
---|---|
Tag | 标签,最基本的信息组织单元,分别用<>和</>标明开头和结尾 |
Name | 标签的名字,<p>...</p>的名字是‘p’,格式:<tag>.name |
Attributes | 标签的属性,字典形式组织,格式:<tag>.attrs |
NavigableString | 标签内非属性字符串,<>...</>中字符串,格式:<tag>.string |
Comment | 标签内字符串的注释部分,一种特殊的Comment类型 |
基于bs4库的HTML内容遍历方法
import requests
from bs4 import BeautifulSoup
r = requests.get("http://python123.io/ws/demo.html")
demo = r.text
soup = BeautifulSoup(demo, "html.parser")
标签树的下行遍历
属性 | 说明 |
---|---|
.contents | 子节点的列表,将<tag>所有子节点存入列表 |
.children | 子节点的迭代类型,与.contents类似,用于循环遍历子节点 |
.descendants | 子孙节点的迭代类型,包含所有子孙节点,用于循环遍历 |
标签树的上行遍历
属性 | 说明 |
---|---|
.parent | 节点的父标签 |
.parents | 节点先辈标签的迭代类型,用于循环遍历先辈节点 |
标签树的平行遍历
属性 | 说明 |
---|---|
.next_sibling | 返回按照HTML文本顺序的下一个平行节点标签 |
.previous_sibling | 返回按照HTML文本顺序的上一个平行节点标签 |
.next_siblings | 迭代类型,返回按照HTML文本顺序的后续所有平行节点标签 |
.previous_siblings | 迭代类型,返回按照HTML文本顺序的前续所有平行节点标签 |
基于bs4库的HTML内容查找方法
<>.find_all(name, attrs, recursive, string, **kwargs)
返回一个列表类型存储查找的结果
name:对标签名称的检索字符串
attrs:对标签属性值的检索字符串,可标注属性检索
recursive:是否对子孙全部搜索,默认True
string:<>...</>中字符串区域的检索字符串
扩展方法
方法 | 说明 |
---|---|
<>.find() | 搜索且只返回一个结果,字符串类型,同.find_all()参数 |
<>.find_parents() | 在先辈节点中搜索,返回列表类型,同.find_all()参数 |
<>.find_parent() | 在先辈节点中返回一个结果,字符串类型,同.find()参数 |
<>.find_next_siblings() | 在后续平行节点中搜索,返货列表类型,同.find_all()参数 |
<>.find_next_sibling() | 在后续平行节点中返回一个结果,字符串类型,同.find()参数 |
<>.find_prrevious_siblings() | 在前续平行节点中,返回一个列表类型,同.find_all()参数 |
<>.find_previous_sibling() | 在前序平行节点中返回一个结果,字符串类型,同.find()参数 |
实例:中国大学排名定向爬虫
功能描述
- 输入:大学排名URL链接
- 输出:大学排名信息的屏幕输出(排名,大学名称,总分)
- 技术线路:requests-bs4
- 定向爬虫:仅对输入URL进行爬取,不扩展爬取
程序的结构设计
- 步骤1:从网络上获取大学排名内容getHTMLText()
- 步骤2:提取网页内容中信息到合适的数据结构fillUnivList()
- 步骤3:利用数据结构展示并输出结果printUnivList()
中文对齐问题
: | <填充> | <对齐> | <宽度> | , | <.精度> | <类型> |
---|---|---|---|---|---|---|
引导符号 | 用于填充的单个字符 | <左对齐 ^右对齐 >居中对齐 | 槽的设定输出宽度 | 数字的千位分隔符适用于整数和浮点数 | 浮点数小鼠部分的精读或字符串的最大输出长度 | 整数类型b,c,d,o,x,X 浮点数类型e,E,f,% |
import requests
from bs4 import BeautifulSoup
import bs4
def getHTMLText(url):
try:
r = requests.get(url, timeout = 30)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
def fillUnivList(ulist, html):
soup = BeautifulSoup(html, "html.parser")
for tr in soup.find('tbody').children:
if isinstance(tr, bs4.element.Tag):
tds = tr.find_all('td')
ulist.append([tds[0].string, tds[1].string, tds[2].string])
def printUnivList(ulist, num):
tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"
print(tplt.format("排名", "学校名称", "省市", chr(12288))) # 12288 是中文空格的utf-8编码
for i in range(num):
u = ulist[i]
print(tplt.format(u[0], u[1], u[2], chr(12288)))
def main():
uinfo = []
url = "http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html"
html = getHTMLText(url)
fillUnivList(uinfo, html)
printUnivList(uinfo, 20) # 20 univs
if __name__ == "__main__":
main()
正则表达式RE
regular expression
- 通用的字符串表达框架
- 简介表达一组字符串的表达式
- 针对字符串表达“简洁”和“特征”思想的工具
- 判断某字符串的特征归属
正则表达式在文本处理中十分常用
- 表达文本类型的特征(病毒、入侵等)
- 同时查找或替换一组字符串
- 匹配字符串的全部或部分
正则表达式的使用
- 编译:将符合正则表达式语法的字符串转换成正则表达式特征
正则表达式的常用操作符
操作符 | 说明 | 实例 | ||
---|---|---|---|---|
. | 表示任何单个字符 | |||
[] | 字符集,对单个字符给出取值范围 | [abc]表示a、b、c,[a-z]表示a到z单个字符 | ||
1 | 非字符集,对单个字符给出排除范围 | 2表示非a或非b或非c的单个字符 | ||
* | 前一个字符0次或无限次扩展 | abc* 表示ab、abc、abcc、abccc等 | ||
+ | 前一个字符1次或无限次扩展 | abc+ 表示abc、abcc、abccc等 | ||
? | 前一个字符0次或1次扩展 | abc? 表示ab、abc | ||
\ | 左右表达式任意一个 | abc\ | def 表示abc、def | |
{m} | 扩展前一个字符m次 | ab{2}表示abbc | ||
{m, n} | 扩展前一个字符m至n次(含n) | ab{1, 2}c表示abc、abbc | ||
^ | 匹配字符串开头 | ^abc表示abc且在一个字符串开头 | ||
$ | 匹配字符串结尾 | abc$表示abc且在一个字符串的结尾 | ||
() | 分组标记,内部只能使用 \ | 操作符 | (abc)表示abc,(abc\ | def)表示abc、def |
d | 数字,等价于[0-9] | |||
w | 单词字符,等价于[A-Za-z0-9_] |
IP地址形式的正则表达式
(([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5]).){3}([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])
RE库的基本使用
RE库是python的标准库,主要用于字符串匹配
import re
- raw string 类型(原生字符串类型)
re 库采用 raw string 类型表示正则表达式,表示为:r'text'
例如
r'[1-9]d{5}
r'd{3}-d{8}|d{4}-d{7}'
raw string 是不包含转义符的字符串
- string 类型,更繁琐
'[1-9]\d{5}'
'\d{3}-\d{8}|\d{4}-\d{7}'
Re库主要功能函数
函数 | 说明 |
---|---|
re.search() | 在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象 |
re.match() | 从一个字符串的开始位置起匹配正则表达式,返回match对象 |
re.findall() | 搜索字符串,以列表类型返回全部能匹配的字串 |
re.split() | 将一个字符串按照正则表达式匹配结果进行分割,返回列表类型 |
re.finditer() | 搜索字符串,返回一个匹配结果的迭代匹配类型,每个迭代元素是match对象 |
re.sub() | 在一个字符串中替换所有匹配正则表达式的字串,返回替换后的字符串 |
re.search(pattern, string, flags=0)
pattern:正则表达式的字符串或原生字符串表示
string:待匹配字符串
flags:正则表达式使用时的控制标记
常用标记 | 说明 |
---|---|
re.I re.IGNORECASE | 忽略正则表达式的大小写,[A-Z]能够匹配小写字符串 |
re.M re.MULTILINE | 正则表达式中的^操作符能够将给定字符串的每行当作匹配开始 |
re.S re.DOTALL | 正则表达式中的.操作符能够匹配所有字符,默认匹配除换行外的所有字符 |
re.match(pattern, string, flags=0)
pattern:正则表达式的字符串或原生字符串表示
string:待匹配字符串
flags:正则表达式使用时的控制标记
re.findall(pattern, string, flags=0)
pattern:正则表达式的字符串或原生字符串表示
string:待匹配字符串
flags:正则表达式使用时的控制标记
re.split(pattern, string, maxsplit=0, flags=0)
pattern:正则表达式的字符串或原生字符串表示
string:待匹配字符串
maxsplit:最大分割数,剩余部分作为最后一个元素输出
flags:正则表达式使用时的控制标记
re.finditer(pattern, string, flags=0)
pattern:正则表达式的字符串或原生字符串表示
string:待匹配字符串
flags:正则表达式使用时的控制标记
re.sub(pattern, repl, string, count=0, flags=0)
pattern:正则表达式的字符串或原生字符串表示
repl:替换匹配字符串的字符串
string:待匹配字符串
count:匹配的最大替换次数
flags:正则表达式使用时的控制标记
两种正则表达式的使用方式
# 函数式用法:一次性操作
rst = re.search(r'[1-9]\d{5}', 'BIT 100081)
# 面向对象用法:编译后的多次操作
pat = re.compile(r'[1-9]\d{5}')
rst = pat.search('BIT 100081')
re.cimpile(pattern, flags=0)
将正则表达式的字符串形式编译成正则表达式对象
pattern:正则表达式的字符串或原生字符串表示
flags:正则表达式使用时的控制标记
Re库的另一种等价用法
函数 | 说明 |
---|---|
regex.search() | 在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象 |
re.match() | 从一个字符串的开始位置起匹配正则表达式,返回match对象 |
regex.findall() | 搜索字符串,以列表类型返回全部能匹配的字串 |
regex.split() | 将一个字符串按照正则表达式匹配结果进行分割,返回列表类型 |
regex.finditer() | 搜索字符串,返回一个匹配结果的迭代匹配类型,每个迭代元素是match对象 |
regex.sub() | 在一个字符串中替换所有匹配正则表达式的字串,返回替换后的字符串 |
调用以上方法时,只需要把原方法中的pattern参数去掉
Re库的match对象
Match对象的属性
属性 | 说明 |
---|---|
.string | 带匹配的文本 |
.re | 匹配时使用的pattern对象(正则表达式) |
.pos | 正则表达式搜索文本的开始位置 |
.endpos | 正则表达式搜索文本的结束位置 |
Match对象的方法
方法 | 说明 |
---|---|
.group(0) | 获得匹配后的字符串 |
.start() | 匹配字符串在原始字符串的开始位置 |
.end() | 匹配字符串在原始字符串的结束位置 |
.span() | 返回(.start(),.end()) |
更多group(n)方法请阅读相关文档
Re库的贪婪匹配和最小匹配
match = re.search(r'PY.*N', 'PYANBCNDN')
match.group(0)
贪婪匹配
Re库默认采用贪婪匹配,即输出匹配最长的字串
最小匹配
match = re.search(r'PY.*?N', 'PYANBCNDN')
match.group(0)
最小匹配操作符
操作符 | 说明 |
---|---|
*? | 前一个字符0次或无限次扩展,最小匹配 |
+? | 前一个字符1次或无限次扩展,最小匹配 |
?? | 前一个字符0次或1次扩展,最小匹配 |
{m, n}? | 扩展前一个字符m至n次(含n),最小匹配 |
实例:淘宝比价定向爬虫
第二页https://s.taobao.com/search?q=书包&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.2017.201856-taobao-item.1&ie=utf8&s=44
第三页https://s.taobao.com/search?q=书包&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.2017.201856-taobao-item.1&ie=utf8&s=88
功能描述
- 目标:获取淘宝搜索页面的信息,提取其中的商品名称和价格
理解:
- 淘宝的搜索接口
- 翻页的处理
- 技术路线:requests-re
程序的结构设计
- 步骤1:提交商品搜索请求,循环获取页面
- 步骤2:对于每个页面,提取商品名称和价格信息
- 步骤3:将信息输出到屏幕上
import requests
import re
def getHTMLText(url):
try:
r = requests.get(url, timeout = 30)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
def parsePage(ilt, html):
try:
plt = re.findall(r'\"view_price\"\:\"[\d\.]*\"', html)
tlt = re.findall(r'\"raw_title\"\:\".*?\"', html)
for i in range(len(plt)):
price = eval(plt[i].split(':')[1])
title = eval(tlt[i].split(':')[1])
ilt.append([price, title])
except:
print("")
def printGoodsList(ilt):
tplt = "{:4}\t{:8}\t{:16}"
print(tplt.format("序号", "价格", "商品名称"))
count = 0
for g in ilt:
count = count + 1
print(tplt.format(count, g[0], g[1]))
def main():
goods = '书包'
depth = 2
start_url = 'https://s.taobao.com/search?q=书包&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.2017.201856-taobao-item.1&ie=utf8' + goods
infoList = []
for i in range(depth):
try:
url = start_url + '&s=' + str(44 * i)
html = getHTMLText(url)
parsePage(infoList, html)
except:
print("exception")
printGoodsList(infoList)
if __name__ == "__main__":
main()
实例:股票数据定向爬虫
百度股票:http://gupiao.baidu.com/stock
功能描述
- 目标:获取上交所和深交所所有股票的名称和交易信息
- 输出:保存到文件中
- 技术线路:requests-bs4-re
候选数据网站的选择:
- 选取原则:股票信息静态存在于HTML页面中,非js代码生成,没有Robots协议限制
- 选取方法:浏览器F12,源代码查看等
- 选取心态:不要纠结于某个网站,多找信息源尝试
程序结构设计
- 步骤1:从东方财富网获取股票列表
- 步骤2:根据股票列表逐个到百度股票获取个股信息
- 步骤3:将结果存储到文件
import requests
import re
from bs4 import BeautifulSoup
import traceback
def getHTMLText(url, code='utf-8'):
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = code
return r.text
except:
return""
def getStockList(lst, stockURL):
html = getHTMLText(stockURL)
soup = BeautifulSoup(html, "html.parser")
a = soup.find_all('a')
for i in a :
try:
href = i.attrs['href']
lst.append(re.findall(r"[s][hz]\d{6}", href)[0])
except:
continue
def getStockInfo(lst, stockURL, fpath):
count = 0
for stock in lst:
url = stockURL + stock + ".html"
html = getHTMLText(url)
try:
if html == "":
continue
infoDict = {}
soup = BeautifulSoup(html, "html.parser")
stockInfo = soup.find('div', attrs={'class':'stock-bets'})
name = stockInfo.find_all(attrs={'class':'bets-name'})[0]
infoDict.update({'股票名称':name.text.split()[0]})
keyList = stockInfo.find_all('dt')
valueList = stockInfo.find_all('dd')
for i in range(len(keyList)):
key = keyList[i].text
val = valueList[i].text
infoDict[key] = val
with open(fpath, 'a', encoding='utf-8') as f:
f.write(str(infoDict) + '\n')
count = count + 1
print("\r当前进度:{:.2f}%".format(count * 100 / len(lst)), end="")
except:
count = count + 1
print("\r当前进度:{:.2f}%".format(count * 100 / len(lst)), end="")
continue
def main():
stock_list_url = "http://quote.eastmoney.com/stocklist.html"
stock_info_url = "http://gupiao.baidu.com/stock/"
output_file = "G:/Code/python/mooc爬虫/BaiduStockInfo.txt"
slist = []
getStockList(slist, stock_list_url)
getStockInfo(slist, stock_info_url, output_file)
main()
Scrapy爬虫框架
pip install scrapy
爬虫框架
- 爬虫框架是实现爬虫功能的一个软件结构和功能组件集合
- 爬虫框架是一个半成品,能够帮助用户实现专业网络爬虫
Scrapy爬虫框架结构
“5+2”结构
- ENGINE
- SCHEDULER
- ITEM PIPELINES
- SPIDERS
- DOWNLOADER
Scrapy爬虫框架解析
Engine
- 控制所有模块之间的数据流
- 根据条件触发事件
Downloader
- 根据请求下载网页
Scheduler
- 对所有请求进行调度管理
Downloader Middleware
- 目的:试试Engine、Scheduler和Downloader之间进行用户可配置的控制
- 功能:修改、丢弃、新增请求或响应
Spider
- 解析Downloader返回的响应(Response)
- 产生爬取项(scraped item)
- 产生额外的爬取请求(Request)
Item Pipelines
- 以流水线方式处理Spider产生的爬取项
- 由一组操作顺序组成,类似流水线,每个操作是一个 Item Pipeline 类型
- 可能操作包括:清理、检验和查重爬取项中的HTML数据、将数据存储到数据库
Spider Middleware
- 目的:对请求和爬取项的再处理
- 功能:修改、丢弃、新增请求或爬取项
requests vs. Scrapy
相同点
- 两者都可以进行页面请求和爬取,Python爬虫的两个重要技术线路
- 两者可用性都好,文档丰富,入门简单
- 两者都没有处理js、提交表单、应对验证码等功能(可扩展)
不同点
requests | Scrapy |
---|---|
页面级爬虫 | 网站级爬虫 |
功能库 | 框架 |
并发性考虑不足 | 并发性好,性能较高 |
重点在于页面下载 | 重点在于爬虫结构 |
定制灵活 | 一般定制灵活,深度定制困难 |
上手十分简单 | 上手稍难 |
Scrapy爬虫的常用命令
Scrapy是为持续运行设计的专业爬虫框架,提供操作的Scrapy命令行
scrapy <command> [options] [args]
Scrapy常用命令
命令 | 说明 | 格式 |
---|---|---|
startproject | 创建一个新工程 | scrapy startproject <name> [dir] |
genspider | 创建一个爬虫 | scrapy genspider [options] <name> [domain] |
settings | 获得爬虫配置信息 | scrapy settings [options] |
crawl | 运行一个爬虫 | scrapy crawl <spider> |
list | 列出工程中所有爬虫 | scrapy list |
shell | 启动URL调试命令行 | scrapy shell [url] |
Scrapy爬虫基本使用
待续