目录

python网络爬虫与信息提取

Requests库入门

HTTP协议及Requests库方法

Requests库的get()方法

Requests库的安装

Requests库主要方法解析

爬取网页的通用代码框架

Robots协议

Robots协议的遵守方式

requests库网络爬虫实战五个实例

实例1:京东商品页面的爬取

实例2:亚马逊商品页面的爬取

实例3:百度360搜索关键词提交

实例4:网络图片的爬取与储存

实例5:IP地址归属地的自动查询

Beautiful Soup库入门

Beautiful Soup库安装

Beautiful Soup库的基本元素

基于bs4库的HTML内容遍历方法

基于bs4库的HTML格式输出

信息组织与提取方法

信息标记得到三种形式

三种信息标记形式的比较

信息提取的一般方法

基于bs4库的HTML内容查找方法

扩展方法

实例:中国大学排名爬虫

中国大学排名定向爬虫介绍

中国大学排名定向爬虫编写

「中国大学排名定向爬虫」实例优化

Re(正则表达式)库入门

正则表达式的概念

正则表达式的语法

Re库的基本使用

Re库的Match对象

Re库的贪婪匹配和最小匹配

实例2:淘宝商品比价定向爬虫

「淘宝商品比价定向爬虫」实例介绍

程序的结构设计

「淘宝商品比价定向爬虫」实例编写

实例3:股票数据定向爬虫

「股票数据定向爬虫」实例介绍

「股票数据定向爬虫」实例编写

「股票数据定向爬虫」实例优化

Scrapy爬虫框架

Scrapy爬虫框架介绍

Scrapy爬虫框架解析

requests库和Scrapy爬虫的比较

Scrapy爬虫的常用命令

Scrapy爬虫的基本使用

Scrapy爬虫的第一个实例

yield关键字的使用

Scrapy爬虫的基本使用

实例4:股票数据Scrapy爬虫

「股票数据Scrapy爬虫」实例介绍

「股票数据Scrapy爬虫」实例编写


python网络爬虫与信息提取

Requests库入门

HTTP协议及Requests库方法

requests库的七个主要方法

 request.request() #构建一个请求,支撑以下各方法的基础方法request.get()   #获取HTML网页的主要方法,对应于HTTP的GETrequest.head()  #获取HTML网页头信息的方法,对应于HTTP的HEADrequest.post()  #向HTML网页提交POST请求的方法,对应于HTTP的POSTrequest.put()   #向HTML网页提交PUT请求的方法,对应于HTTP的PUTrequest.patch() #向HTML网页提交局部修改请求,对应于HTTP的PATCHrequest.delete()#向HTML页面提交删除请求,对应于HTTP的Delete

HTTP协议

HTTP,超文本传输协议。

HTTP是一个基于「请求与响应」模式的、无状态的应用层协议。

HTTP协议采用URL作为定位网络资源的标识。

URL格式 http://host:port

host:合法的internet主机域名或IP地址

port:端口号,缺省端口为80

path:请求资源的路径

HTTP URL的理解:

URL是通过HTTP协议存取资源的Internet路径,一个URL对应一个数据资源。

HTTP协议对资源的操作

 GET     #请求获取URL位置的资源HEAD    #请求获取URL位子资源的响应消息报告,即获得该资源的头部信息POST    #请求向URL位子的资源后附加新的数据PUT     #请求向URL位置存储一个资源,覆盖原URL位置的资源PATCH   #请求局部更新URL位置的资源,即改变该处资源的部分内容DELETE  #请求删除URL位置存储的资源

理解PATHC和PUT的区别

假设URL位置有一组数据UserInfo,包括UserID、UserName等20个字段。

需求:用户改变了UserName,其他不变。

*采用PATCH,仅向URL提交UserName的局部更新请求。

*采用PUT,必须将所有20个字段一并提交到URL,未提交字段被删除

PATCH的主要好处:节省网络带宽

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表示连接成功,404表示失败(只要不是200都是失败)r.text #HTTP响应内容的字符串形式,即,url对应的页面内容r.encoding#从HTTP header中猜测的响应内容编码方式r.apparent_encoding#从内容中分析出的响应内容编码方式(备选编码方式)r.content #HTTP响应内容的二进制形式

r.encoding:如果header中不存在charset,则认为编码为ISO-8859-1

r.apparent_encoding:根据网页内容分析出的编码方式

当r.encoding显示乱码时,使用r.apparent_encoding来解码相关信息。

Requests库的安装

 pip install requests

Requests库主要方法解析

request.request(method,url,**kwargs)

method:请求方式,对应get/put/post等七种方法

url:获取页面的url链接

**kwargs:控制访问的参数,共13个

 #method:请求方式r=requests.request('GET',url,**kwargs)r=requests.request('HEAD',url,**kwargs)r=requests.request('POST',url,**kwargs)r=requests.request('PUT',url,**kwargs)r=requests.request('PATCH',url,**kwargs)r=requests.request('delete',url,**kwargs)r=requests.request('OPTIONS',url,**kwargs) #获取服务器与客户端可以打交道的参数
 r=requests.request(method,url,**kwargs)#**kwargs:控制访问的参数,均为可选项

params

params:字典或字节序列,作为参数增加到url中

例:

kv = {'key1':'value1','key2':'value2'} r = requests.request('GET',url,params=kv) print(r.url) 返回:url?key1=value1&key2=value2

data

data:字典、字节序列或文件对象,作为request的内容

例:

kv = {'key1':'value1','key2':'value2'} r = requests.request('POST',url,data=kv) body = '主体内容' r = requests.request('POST',url,data=body)

json

json:JSON格式的数据,作为request的内容

例:

kv = {'key1':'value1','key2':'value2'} r = requests.request('POST',url,json=kv)

headers

headers:字典,HTTP定制头

可以模拟任何想模拟的浏览器向服务器发起访问

例:

hd={'user-agent':'chrome/10'}

r = requests.request('POST',url,headers=hd)

cookies

cookies:字典或CookieJar,Request中的cookie

auth

auth:元组,支持HTTP认证功能

files

files:字典类型,传输文件

可以向某个特定的链接提交文件

例:

fs = {'file':open('data.xls','rb')}

r = requests.request('POST',url,files=fs)

timeout

timeout:设定超时时间,秒为单位

在请求时间内没有返回回来,那么会产生一个timeout异常

例:

r = requests.request('GET',url,timeout=10)

proxies

proxies:字典类型,设定访问代理服务器,可以增加登录认证

可以有效隐藏爬取网页的源IP地址信息

例:

pxs = {'http':'url' ,'https':'url2'}

r = requests.request('GET',url,proxies=pxs)

allow_redirects,stream,verify,cert

allow_redirects: True/False,默认为True,重定向开关

stream:True/False,默认为True,获取内容立即下载开关

verify:True/False,默认为True,认证SSL证书开关

cert:本地SSL证书路径

爬取网页的通用代码框架

 try:r = requests.get(url,timeout=30)r.raise_for_status() #如果状态码不是200,将产生一次异常r.encoding = r.apparent_encodingreturn r.textexcept:return "产生异常"#网络连接有风险,异常处理很重要

理解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(url,timeout=30)r.raise_for_status() #如果状态码不是200,将产生一次异常r.encoding = r.apparent_encodingreturn r.textexcept:return "产生异常"if __name__=="__main__":url= 'http://www.baidu.com'print(getHTMLText(url))

Robots协议

Robots协议:网络爬虫排除协议

作用:网站告知爬虫哪些页面可以抓取,哪些不行。

形式:在网站根目录下的robots.txt文件

User-agent:* :任何爬虫

Disallow:/? :不允许访问以问号开头的路径

Robots协议的遵守方式

网络爬虫:自动或人工识别robots.txt,再进行内容爬取。

约束性:Robots协议是建议但非约束性,网络爬虫可以不遵守,但存在法律风险。

类人行为可不参考robots协议

requests库网络爬虫实战五个实例

实例1:京东商品页面的爬取

import requests
url = "https://item.jd.con/2967929.html"
try:r = requests.get(url,timeout=30)r.raise_for_status() #如果状态码不是200,将产生一次异常r.encoding = r.apparent_encodingprint(r.text)
except:print("产生异常")

实例2:亚马逊商品页面的爬取

import requests
url = "任意亚马逊商品页面"
try:kv = {'user-agent':'Mozilla/5.0'}r = requests.get(url,timeout=30,headers=kv)r.raise_for_status() #如果状态码不是200,将产生一次异常r.encoding = r.apparent_encodingprint(r.text)
except:print("产生异常")

实例3:百度360搜索关键词提交

import requests
keyword = "python"
url = 'http://www.baidu.com/s'
try:kv = {'wd':keyword}r = requests.get(url,timeout=30,params=kv)r.raise_for_status() #如果状态码不是200,将产生一次异常r.encoding = r.apparent_encodingprint(len(r.text)
except:print("产生异常")# 360
import requests
keyword = "python"
url = 'http://www.so.com/s'
try:kv = {'wd':keyword}r = requests.get(url,timeout=30,params=kv)r.raise_for_status() #如果状态码不是200,将产生一次异常r.encoding = r.apparent_encodingprint(len(r.text)
except:print("产生异常")#弹幕提示pip一个fake_useragent库,避免反扒

实例4:网络图片的爬取与储存

import requests
import os
url ="图片地址"
root = "D://PICS//" #存储地址
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)f.close()print("文件保存成功")
except:print("爬取失败")
#因为反扒原因,爬取失败

实例5:IP地址归属地的自动查询

import requests
url = "IP地址查询网站接口"
try:kv = {'user-agent':'Mozilla/5.0'}r = requests.get(url+'想查询的IP地址',timeout=30,headers=kv)r.raise_for_status() #如果状态码不是200,将产生一次异常r.encoding = r.apparent_encodingprint(r.text)
except:print("产生异常")

Beautiful Soup库入门

Beautiful Soup库安装

pip install beautifulsoup4

from bs4 import BeautifulSoup
soup = BeautifulSoup('<p>data</p>','html.parser')

Beautiful Soup库的基本元素

Beautiful Soup库是解析、遍历、维护「标签树」的功能库

Beautiful Soup对应一个HTML/XML文档的全部内容

Beautiful Soup库解析器

bs4的HTML解析器:

语法:BeautifulSoup(mk,'html.parser')

条件:安装bs4库

lxml的HTML解析器:

语法:BeautifulSoup(mk,'lxml')

条件:pip install lxml

lxml的xml解析器:

语法:BeautifulSoup(ml,'xml')

条件:pip install lxml

html5lib的解析器:

语法:BeautifulSoup(mk,'html5lib')

条件:pip install html5lib

BeautifulSoup类的基本元素

Tag:标签,醉基本的信息组织单元,分别用<>和</>表明开头和结尾

Name:标签的名字,<p>...</p>的名字是'p',格式:<tag>.name

Attributes:标签的属性,字典形式组织,格式:<tag>.attrs

NavigableString:标签内非属性字符串,<>...</>中的字符串,格式:<tag>.string

Comment:标签内字符串的注释部分,一种特殊的Comment类型

基于bs4库的HTML内容遍历方法

标签树的下行遍历

.contents :子节点的列表,将<tag>所有儿子节点存入列表

.children :子节点的迭代类型,与.contents类似,用于循环遍历儿子节点

.descendants : 子孙节点的迭代类型,包含所有子孙节点,用于循环遍历

for child in soup.body.children:print(child)     #遍历儿子节点
for child in soup.body.descendants:print(child)     #遍历子孙节点

标签树的上行遍历

.parent :节点的父亲标签

.parents:节点先辈标签的迭代类型,用于循环遍历先辈节点

from bs4 import BeautifulSoup as bs
soup = bs('<a>123</a>','html.parser')
for parent in soup.a.parents:if parent is None:print(parent)else:print(parent.name)

标签树的平行遍历

平行遍历发生在同一个父亲节点下的各节点间

.next_sibling:返回按照HTML文本顺序的下一个平行节点标签

.previous_sibling:返回按照HTML文本顺序的上一个平行节点标签

.next_siblings:迭代类型,返回按照HTML文本顺序的后续所有平行节点标签

.previous_siblings:迭代类型,返回按照HTML文本顺序的前续所有平行节点标签

for sibling in soup.a.next_siblings:print(sibling) #遍历后续节点
for sibling in soup.a.previous_siblings:print(sibling) #遍历前续节点

基于bs4库的HTML格式输出

bs4库的prettify()方法

from bs4 import BeautifulSoup as bs
soup = bs('<a>123</a>','html.parser')
soup.a.string #返回:'123'
print(soup.a.prettify()) #返回<a>123</a>

信息组织与提取方法

信息标记得到三种形式

信息的标记

*标记后的信息可形成信息组织结构,增加了信息维度

*标记后的信息可用于通信、存储或展示

*标记的结构与信息一样具有重要价值

*标记后的信息更利于程序理解和运用

HTML的信息标记

HTML通过预定义的<>……</>标签形式组织不同类型的信息

XML

与HTML类似

JOSN

有类型的键值对 "key":"value"

嵌套使用{}

YAML

无类型键值对 key:value

嵌套使用缩进

-表达并列关系

|表达整块数据

#表示注释

例:

name:

-value

-value1

三种信息标记形式的比较

XML:最早的通用信息标记语言,可扩展性好,但繁琐。Internet上的信息交互与传递

JSON:信息有类型,适合程序处理(js),较XML简洁。移动应用云端和节点的信息通信,无注释

YAML:信息无类型,文本信息比例最高,可读性好。各类系统的配置文件,有注释,易读

信息提取的一般方法

方法一:完整解析信息的标记形式,再提取关键信息。

需要标记解释器 例如:bs4库的标签树遍历

优点:信息解析准确

缺点:提取过程繁琐,速度慢

方法二:无视标记形式,直接搜索关键信息。

对信息的文本查找函数即可。

优点:提取过程简洁,速度较快

缺点:提取结果准确性与信息内容相关

融合方法:结合形式解析与搜索方法,提取关键信息。

需要标记解析器及文本查找函数。

实例:提取HTML中所有URL链接

思路:1)搜索到所有<a>标签

2)解析<a>标签格式,提取href后的链接内容

from bs4 import BeautifulSoup as bs
import requests
r = requests.get("http://python123.io/ws/demo.html")
demo = r.textsoup = bs(demo,'html.parser')
for link in soup.find_all('a'):print(link.get('href'))

基于bs4库的HTML内容查找方法

fand_all(name,attrs,recursive,string,**kwargs)

返回一个标签类型,存储查找的结果。

name:对标签名称的检索字符串。

attrs:对标签属性值的检索字符串,可标注属性检索。

recursive:是否对子孙全部检索,默认True。

string:<>……</>中字符串区域的检索字符串。

<tag>(……)等价于<tag>.find_all(……)

soup(……)等价于soup.find_all(……)

扩展方法

<>.find

搜索且只返回一个结果,字符串类型,同.find_all()参数

<>.find_parents()

在先辈节点中搜索,返回列表类型,

<>.find_parent()

在先辈节点中返回一个结果,字符串类型,

<>.find_nex_siblings()

在后续平行节点中搜索,返回列表类型,

<>.find_next_sibling()

在后续平行节点中返回一个结果,字符串类型,

<>.find_previous_siblings()

在前序平行节点中搜索,返回列表类型,

<>.find_previous_sibling()

在前序平行节点中返回一个结果,字符串类型

实例:中国大学排名爬虫

中国大学排名定向爬虫介绍

功能描述

输入:大学排名URL链接

输出:大学排名信息的屏幕输出(排名,大学名称,总分)

技术路线:requests——bs4

定向爬虫:仅对输入URL进行爬取,不扩展爬取

程序的结构设计

步骤一:从网络上获取大学排名网页内容——getHTMLText()

步骤二:提取网页内容中信息到合适的数据结构——fillUnivList()

步骤三:利用数据结构展示并输出结果——printUnivList()

中国大学排名定向爬虫编写

import requests
from bs4 import BeautifulSoup
import bs4def getHTMLText(url):try:r = requests.get(url, timeout=30)r.raise_for_status()r.encoding = r.apparent_encodingreturn r.textexcept: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('td')ulist.append([tds[0].string, tds[1].string, tds[3].string])def printUnivList(ulist, num):print("{:^10}\t{:^6}\t{:^10}".format("排名","学校名称","总分"))for i in range(num):u=ulist[i]print("{:^10}\t{:^6}\t{:^10}".format(u[0],u[1],u[2]))def main():uinfo = []url = 'https://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html'html = getHTMLText(url)fillUnivList(uinfo, html)printUnivList(uinfo, 20) # 20 univs
main()

「中国大学排名定向爬虫」实例优化

解决了中文输出的问题

import requests
from bs4 import BeautifulSoup
import bs4def getHTMLText(url):try:r = requests.get(url, timeout=30)r.raise_for_status()r.encoding = r.apparent_encodingreturn r.textexcept: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('td')ulist.append([tds[0].string, tds[1].string, tds[3].string])def printUnivList(ulist, num):tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"print(tplt.format("排名","学校名称","总分",chr(12288)))for i in range(num):u=ulist[i]print(tplt.format(u[0],u[1],u[2],chr(12288)))def main():uinfo = []url = 'https://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html'html = getHTMLText(url)fillUnivList(uinfo, html)printUnivList(uinfo, 20) # 20 univs
main()

Re(正则表达式)库入门

正则表达式的概念

正则表达式是用来简洁表达一组字符串的表达式。

*通用的字符串表达框架

*简洁表达一组字符串的表达式

*针对字符串表达「简洁」和「特征」思想的工具

*判断某字符串的特征归属

正则表达式阿紫文本处理中十分常用

*表达文本类型的特征(病毒、入侵等)

*同时查找或替换一组字符串

*匹配字符串的全部或部分

正则表达式的使用

*编译:将符合正则表达式语法的字符串转换成正则表达式特征。

正则表达式的语法

基础语法

正则表达式语法由字符和操作符构成

.:表示任何单个字符

[]:字符集,对单个字符给出取值范围

[^]:非字符集,对单个字符给出排除范围

*:前一个字符0次或无限次扩展

+:前一个字符1次或无限次扩展

?:前一个字符0次或1次扩展

|:左右表达式任意一个

{m}:扩展前一个字符M次

{m,n}:扩展前一个字符m至n次(含n)

^:匹配字符串开头

$:匹配字符串结尾

():分组标记,内部职能使用|操作符

\d:数字,等价于[0-9]

\w:单词字符,等价于[A-Za-z0-9_]

正则表达式语法实例

P(Y|YT|YTH|YTHO)?N 对应:'PY'、 'PYN'、 'PYTN'、 'PYTHN '、 'PYTHON'

PYTHON+ 对应:'PYTHON'、'PYTHONN'、'PYTHONNN'

经典正则表达式实例

^[A-Za-z]+$ 由26个字母组成的字符串

^[A-Za-z0-9]+$ 由26个字母和数字组成的字符串

^-?\d+$ 整数形式的字符串

^[0-9]*[1-9] [0-9] *$ 正整数形式的字符串

[1-9]\d{5} 中国境内邮政编码,6位

[\u4e00-\u9fa5] 匹配中文字符

\d{3}-\d{8}|\d{4}-\d{7} 国内电话号码,010-68913536

Re库的基本使用

Re库是Python的标准库,主要用于字符串匹配

调用方法:import re

正则表达式的表示类型

*raw string类型(原生字符串类型)

re库采用raw string类型表示正则表达式,表示为:r'text'

例如:r'[1-9]\d{5}'

raw string是不包含转义符的字符串

*string类型,更繁琐

例如:'[1-9]\d{5}'

Re库主要功能函数

re.search(pattern,string,flags=0)

在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象

pattern:正则表达式的字符串或原生字符串表示

string:待匹配的字符串

flags:正则表达式使用时的控制标记

re.match(pattern,string,flags=0)

从一个字符串的开始位置起匹配正则表达式,返回match对象

re.findall(pattern,string,flags=0)

搜索字符串,以列表类型返回全部能匹配的子串

re.split(pattern,string,maxsplit=0,flags=0)

将一个字符串按照正则表达式匹配结果进行分割,返回列表类型

maxsplit:最大分割数,剩余部分作为最后一个元素输出

re.finditer(pattern,string,flags=0)

搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素都是match对象

re.sub(pattern,repl.string,count=0,flags=0)

在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串

repl:替换匹配字符串的字符串

count:匹配的最大替换次数

flags:正则表达式使用时的控制标记

re.I re.IGNORECASE:忽略正则表达式的大小写,[A-Z]能够匹配小写字符

re.M re.MULTILINE:正则表达式中的^操作符能够将给定字符串的每行当做匹配开始

re.S re.DOTALL:正则表达式中的.操作符能够匹配所有字符,默认匹配除换行外的所有字符

Re库的另一种等价用法

函数式用法:一次性操作

res = re.search(r'[1-9]\d{5}','BIT 100081')

面向对象用法:编译后的多次操作

pat = re.compile(r'[1-9]\d{5}')

rst = pat.search('BIT 100081')

re.compile(pattern,flags=0)

将正则表达式的字符串形式编译成正则表达式对象

例:regex = re.compile(r'[1-9]\d{5}')

Re库的Match对象

Match对象的属性

.string:待匹配的文本

.re:匹配时使用的pattern对象(正则表达式)

.pos:正则表达式搜索文本的开始位置

.endpos:正则表达式搜索文本的结束位置

Match对象的方法

.group(0):获得匹配后的字符串 #有更多的使用方法

.start():匹配字符串在原始字符串的开始位置

.end():匹配字符串在原始字符串的结束位置

.span():返回(.start(),.end())

Re库的贪婪匹配和最小匹配

实例

match = re.search(r'PY.*n','PYANBNCNDN')
match.group(0)
#Re库默认采用贪婪匹配,即输出匹配最长的子串。#最小匹配
match = re.search(r'PY.*?n','PYANBNCNDN')
match.group(0)

最小匹配操作符

*?:前一个字符0次或无限次扩展,最小匹配

+?:前一个字符1次或无限次扩展,最小匹配

??:前一个字符0次或1次扩展,最小匹配

{m,n}?:前一个字符M至N次(含n),最小匹配

实例2:淘宝商品比价定向爬虫

「淘宝商品比价定向爬虫」实例介绍

目标:获取淘宝搜索页面的信息,提取其中的商品名称和价格

理解:淘宝的搜索接口,翻页的处理

技术路线:requests-re

https://s.taobao.com/search?q=%E4%B9%A6%E5%8C%85&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.21814703.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170306&bcoffset=1&ntoffset=1&p4ppushleft=2%2C48&s=44

程序的结构设计

步骤1:提交商品搜索请求,循环获取页面

步骤2:对于每个页面,提取商品名称和价格信息

步骤3:将信息输出到屏幕上

「淘宝商品比价定向爬虫」实例编写

 #CrowTaobaoPrice.py#由于采用JS渲染,此爬虫已失效,仅供参考import requestsimport re​def getHTMLText(url):try:r = requests.get(url, timeout=30)r.raise_for_status()r.encoding = r.apparent_encodingreturn r.textexcept: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 = 0for g in ilt:count = count + 1print(tplt.format(count, g[0], g[1]))def main():goods = '书包'depth = 3start_url = 'https://s.taobao.com/search?q=' + goodsinfoList = []for i in range(depth):try:url = start_url + '&s=' + str(44*i)html = getHTMLText(url)parsePage(infoList, html)except:continueprintGoodsList(infoList)

实例3:股票数据定向爬虫

「股票数据定向爬虫」实例介绍

目标:获取上交所和深交所所有股票的名称和交易信息

输出:保存到文件中

技术路线:requests-bs4-re

候选数据网站的选择

选取原则:股票信息静态存在于HTML页面中,非JS代码生成,没有Robots协议限制

选取方法:浏览器F12,源代码查看等

选取心态:不要纠结于某个网站,多找信息源尝试

程序的结构设计

步骤1:从东方财富网获取股票列表

步骤2:根据股票列表逐个到百度股票获取个股信息

步骤3:将结果存储到文件

「股票数据定向爬虫」实例编写

 #CrawBaiduStocksA.py#无法适用于JS渲染的页面import requestsfrom bs4 import BeautifulSoupimport tracebackimport re​def getHTMLText(url):try:r = requests.get(url)r.raise_for_status()r.encoding = r.apparent_encodingreturn r.textexcept: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):for stock in lst:url = stockURL + stock + ".html"html = getHTMLText(url)try:if html=="":continueinfoDict = {}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].textval = valueList[i].textinfoDict[key] = valwith open(fpath, 'a', encoding='utf-8') as f:f.write( str(infoDict) + '\n' )except:traceback.print_exc()continue​def main():stock_list_url = 'https://quote.eastmoney.com/stocklist.html'stock_info_url = 'https://gupiao.baidu.com/stock/'output_file = 'D:/BaiduStockInfo.txt'slist=[]getStockList(slist, stock_list_url)getStockInfo(slist, stock_info_url, output_file)​main()

「股票数据定向爬虫」实例优化

 #CrawBaiduStocksB.pyimport requestsfrom bs4 import BeautifulSoupimport tracebackimport re​def getHTMLText(url, code="utf-8"):try:r = requests.get(url)r.raise_for_status()r.encoding = codereturn r.textexcept:return ""​def getStockList(lst, stockURL):html = getHTMLText(stockURL, "GB2312")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 = 0for stock in lst:url = stockURL + stock + ".html"html = getHTMLText(url)try:if html=="":continueinfoDict = {}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].textval = valueList[i].textinfoDict[key] = valwith open(fpath, 'a', encoding='utf-8') as f:f.write( str(infoDict) + '\n' )count = count + 1print("\r当前进度: {:.2f}%".format(count*100/len(lst)),end="")except:count = count + 1print("\r当前进度: {:.2f}%".format(count*100/len(lst)),end="")continue​def main():stock_list_url = 'https://quote.eastmoney.com/stocklist.html'stock_info_url = 'https://gupiao.baidu.com/stock/'output_file = 'D:/BaiduStockInfo.txt'slist=[]getStockList(slist, stock_list_url)getStockInfo(slist, stock_info_url, output_file)​main()

Scrapy爬虫框架

Scrapy爬虫框架介绍

Scrapy的安装

pip install scrapy

安装测试:scrapy -h

Scraoppy爬虫框架结构

爬虫框架:爬虫框架是实现爬虫功能的一个软件结构和功能组件集合

爬虫框架是一个半成品,能够帮助用户实现专业网络爬虫

Scrapy爬虫框架解析

Engine(不需要修改)

控制所有模块之间的数据流

根据条件触发事件

Downloader:根据请求下载网页(不需要修改)

Scheduler:对所有爬取请求进行调度管理(不需要修改)

Downloader Middleware

目的:实施Engine、Scheduler和Downloader之间进行用户可配置的控制

功能:修改、丢弃、新增请求或响应

用户可以编写配置代码

Spider(需要用户编写配置代码)

解析Downloader返回的响应(Response)

产生爬取项(scraped item)

产生额外的爬取请求(Request)

Item Pipelines(需要用户编写配置文件)

以流水线方式处理Spider产生的爬取项

由一组操作顺序组成,类似流水线,每一个操作是一个Item Pipeline类型

可能操作包括:清理、检验和查重爬取项中的HTML数据、将数据存储到数据库

Spider Middleware(用户可以编写配置代码)

目的:对请求和爬取项的再处理

功能:修改、丢弃、新增请求或爬取项

requests库和Scrapy爬虫的比较

相同点

两者都可以进行页面请求和爬取,python爬虫的两个重要技术路线

两者可用性都好,文档丰富,入门简单

两者都没有处理js、提交表单、应对验证码等功能(可扩展)

不同点

requests

页面级爬虫

功能库

并发性考虑不足,性能较差

重点在于页面下载

定制灵活

上手十分简单

Scrapy

网站级爬虫

框架

并发性好,性能较高

重点在于爬虫结构

一般定制灵活,深度定制困难

入门较难

选用哪个技术路线开发爬虫

非常小的需求,requests库

不太小的需求,Scrapy框架

定制程度很高的需求(不考虑规模),自搭框架,requests>Scrapy

Scrapy爬虫的常用命令

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爬虫的命令行逻辑

命令行更容易自动化,适合脚本控制

本质上,Scrapy是给程序员用的,功能更重要

Scrapy爬虫的基本使用

Scrapy爬虫的第一个实例

步骤1:建立一个Scrapy爬虫工程

python123deme:外层目录

scrapy.cfg:部署scrapy爬虫的配置文件

python123deme:scrapy框架的用户自定义python代码

 __init__.py #初始化脚本item.py #item代码模板(继承类)middlewares.py #Middlewares代码模板(继承类)pipelines.py #pipelines代码模板(继承类)settings.py #scrapy爬虫的配置文件spiders/ #spiders代码模板目录(继承类)

步骤2:在工程中产生一个Scrapy爬虫

 scrapy genspider demo python123.io #会在spiders目录下生成一个demo.py#demo.py# -*- coding: utf-8 -*-import scrapyclass DemoSpider(scrapy.Spider):name = "demo"#allowed_domains = ["python123.io"]start_urls = ['https://python123.io/']def parse(self, response): #用于处理响应,解析内容形成字典,发现新的URL爬取请求pass 

步骤3:配置产生的spider爬虫

 #修改后的demo.py# -*- coding: utf-8 -*-import scrapyclass DemoSpider(scrapy.Spider):name = "demo"#allowed_domains = ["python123.io"]start_urls = ['https://python123.io/ws/demo.html']def parse(self, response):fname = response.url.split('/')[-1]with open(fname, 'wb') as f:f.write(response.body)self.log('Saved file %s.' % name)

步骤4:运行爬虫,获取网页

 scrapy crawl demo

yield关键字的使用

yield=生成器

生成器是一个不断产生值的函数

包含yield语句的函数是一个生成器

生成器每次产生一个值(yield语句),函数被冻结,被唤醒后再产生一个值

实例

 #生成器写法def gen(n):for i in range(n):yield i**2for i in gen(5):print(i,"",end="")# 0   1  4  9  16#普通写法def square(n):ls = [i**2 for i in range(n)]return lsfor i in square(5):print(i,"",end="")

生成器相比一次列出所有内容的优势

更节省存储空间

响应更迅速

使用更灵活

生成器写法

 import scrapyclass DemoSpider(scrapy.Spider):name = "demo"#allowed_domains = ["python123.io"]def start_requests(self):urls = ['https://python123.io/ws/demo.html']for url in urls:yield scrapy.Request(url=url,callback=self.pares)def parse(self, response):fname = response.url.split('/')[-1]with open(fname, 'wb') as f:f.write(response.body)self.log('Saved file %s.' % name)

Scrapy爬虫的基本使用

Scrapy爬虫的使用步骤

步骤1:创建一个工程和spider模板

步骤2:编写spider

步骤3:编写item pipelines

步骤4:优化配置策略

Scrapy爬虫的数据类型

Request类:向网络上提交请求的内容

class scrapy.http.Request()

Request对象标识一个HTTP请求

由spider生成,由downloader执行

 .url #Request对应的请求URL地址.method #对应的请求方法,'GET'等.headers #字典类型风格的请求头.body #请求内容主题,字符串类型.meta #用户添加的扩展信息,在Scrapy内部模块间传递信息使用.copy #复制该请求

Response类:从网络上爬取内容的封装类

class scrapy.http.Response()

Response对象表示一个HTTP相应

由Downloader生成,由spider处理

 .url #Response对应的URL地址.status #HTTP状态码,默认是200.headers #Response对应的头部信息.body #Response对应的内容信息,字符串类型.flags #一组标记.request #产生Response类型对应得到Request对象.copy() #复制该响应

Item类:spider产生的信息

class scrapy.item.Item()

Item对象表示一个从HTML页面中提取的信息内容

由spider生成,由Item Pipeline处理

Item类似字典类型,可以按照字典类型操作

Scrapy爬虫提取信息的方法

Scrapy爬虫支持多种HTML信息提取方法

Beautiful Soup,lxml,re,XPath Selector,CSS Selector

CSS Selector的基本使用

<HTML>.css('a::attr(href)').extract() #a-标签名称、href-标签属性

实例4:股票数据Scrapy爬虫

「股票数据Scrapy爬虫」实例介绍

功能描述

技术路线:scrapy

目标:获取上交所和深交所所有股票的名称和交易信息

输出:保存到文件中

「股票数据Scrapy爬虫」实例编写

步骤1:创建一个工程和spider模板

> scrapy startproject BaiduStocks

> cd BaiduStocks

> scrapy genspider stocks baidu.com

进一步修改spiders/stocks.py文件

步骤2:编写spider

配置stocks.py文件

修改对返回页面的处理

修改对新增URL爬取请求的处理

 # -*- coding: utf-8 -*-import scrapyimport re​​class StocksSpider(scrapy.Spider):name = "stocks"start_urls = ['https://quote.eastmoney.com/stocklist.html']​def parse(self, response):for href in response.css('a::attr(href)').extract():try:stock = re.findall(r"[s][hz]\d{6}", href)[0]url = 'https://gupiao.baidu.com/stock/' + stock + '.html'yield scrapy.Request(url, callback=self.parse_stock)except:continue​def parse_stock(self, response):infoDict = {}stockInfo = response.css('.stock-bets')name = stockInfo.css('.bets-name').extract()[0]keyList = stockInfo.css('dt').extract()valueList = stockInfo.css('dd').extract()for i in range(len(keyList)):key = re.findall(r'>.*</dt>', keyList[i])[0][1:-5]try:val = re.findall(r'\d+\.?.*</dd>', valueList[i])[0][0:-5]except:val = '--'infoDict[key]=val​infoDict.update({'股票名称': re.findall('\s.*\(',name)[0].split()[0] + \re.findall('\>.*\<', name)[0][1:-1]})yield infoDict

步骤3:编写item pipelines

配置pipelines.py文件

定义对爬取项(scraped Item)的处理类

 # -*- coding: utf-8 -*-​# Define your item pipelines here## Don't forget to add your pipeline to the ITEM_PIPELINES setting# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html​​class BaidustocksPipeline(object):def process_item(self, item, spider):return item​class BaidustocksInfoPipeline(object):def open_spider(self, spider):self.f = open('BaiduStockInfo.txt', 'w')​def close_spider(self, spider):self.f.close()​def process_item(self, item, spider):try:line = str(dict(item)) + '\n'self.f.write(line)except:passreturn item

配置ITEM_PIPELINES选项

下面是settings.py文件中被修改的区域:

 # Configure item pipelines# See https://scrapy.readthedocs.org/en/latest/topics/item-pipeline.htmlITEM_PIPELINES = {'BaiduStocks.pipelines.BaidustocksInfoPipeline': 300,}

python网络爬虫与信息提取(笔记)【未完】相关推荐

  1. Python网络爬虫与信息提取笔记(续篇)(文末附教学视频)只供教学讲解,请勿对有robots协议的网站(如淘宝网)造成骚扰

    接上篇博客:Python网络爬虫与信息提取笔记(文末附教学视频) 14:基于bs4库的HTML内容遍历方法 标签树的下行遍历: 用len(soup.body.contents)返回body标签的儿子节 ...

  2. Python网络爬虫与信息提取笔记08-实例2:淘宝商品比价定向爬虫

    Python网络爬虫与信息提取笔记01-Requests库入门 Python网络爬虫与信息提取笔记02-网络爬虫之"盗亦有道" Python网络爬虫与信息提取笔记03-Reques ...

  3. python网络爬虫与信息提取_北京理工大学_Python网络爬虫与信息提取(一)

    学习 北京理工大学 嵩天 课程笔记 课程体系结构: 1.Requests框架:自动爬取HTML页面与自动网络请求提交 2.robots.txt:网络爬虫排除标准 3.BeautifulSoup框架:解 ...

  4. python 网页爬虫作业调度_第3次作业-MOOC学习笔记:Python网络爬虫与信息提取

    1.注册中国大学MOOC 2.选择北京理工大学嵩天老师的<Python网络爬虫与信息提取>MOOC课程 3.学习完成第0周至第4周的课程内容,并完成各周作业. 4.提供图片或网站显示的学习 ...

  5. Python网络爬虫与信息提取

    1.Requests库入门 Requests安装 用管理员身份打开命令提示符: pip install requests 测试:打开IDLE: >>> import requests ...

  6. 北京理工大学·Python网络爬虫与信息提取·知识整理

    学习目标: python爬虫部分的学习 学习内容: mooc北京理工大学·Python网络爬虫与信息提取 对Scrapy内核依然一知半解,但mooc内容已经学完整理 后续将对Scrapy继续进行学习 ...

  7. MOOC《Python网络爬虫和信息提取》(第11次)网络爬虫之框架(第4周)

    MOOC<Python网络爬虫和信息提取>(第11次)网络爬虫之框架(第4周) MOOC–Python网络爬虫和信息提取(第11次开课) 网络爬虫之框架 21.08.10 目录 文章目录 ...

  8. 嵩天《Python网络爬虫与信息提取》实例2:中国大学排名定向爬虫

    在介绍完requests库和robots协议后,嵩天老师又重点介绍了如何通过BeautifulSoup库进行网页解析和信息提取.这一部分就是在前面内容的基础上,综合运用requests库和Beauti ...

  9. Python网络爬虫与信息提取—requests库入门

    requests的学习笔记 requests库自动爬取HTML页面,自动网络请求提交 此博客为中国大学MOOC北京理工大学<Python网络爬虫与信息提取>的学习笔记 requests库的 ...

最新文章

  1. [linux]ps结果计算行数
  2. hadoop emr_在Amazon EMR上运行Hadoop MapReduce作业
  3. 二层和三层工业交换机的主要参数说明
  4. 简单好用的计算器:bc
  5. [转]ODAC 应用技巧 (一)使用 ODAC 的 Net 方式
  6. jeecg输入中文查询导表为空_学术利器—SCI期刊影响因子查询/中文核心期刊查询系统更新...
  7. 插入排序(边输边排)
  8. Arcgis Javascript那些事儿(八)--图层获取与图层顺序
  9. 锐捷显示认证服务器不可用,win10系统下锐捷客户端认证失败的解决方法
  10. 【正点原子MP157连载】第四章 ATK-STM32MP157功能测试-摘自【正点原子】STM32MP157快速体验
  11. lg相乘公式_lg的运算法则是什么
  12. 在线制作ico图标源码
  13. vue-study-1 mvx模式
  14. 引用提高 提高 啦啦啦啦啦啦啦啦啦啦了
  15. JAVA应用生产问题排查步骤
  16. CMS是什么?如何识别CMS?
  17. 从零开始的数模(二十)变异系数法
  18. react 返回上一页
  19. 31-最大子矩阵(蓝桥杯)
  20. 全排列Permutation

热门文章

  1. Cookie和session的区别以及安全性_小晓_同学__新浪博客
  2. 添加阿里矢量彩色图标
  3. vmware虚拟机桥接设置 与主机进行通讯
  4. php面试上机测试题_PHP面试题及答案
  5. ant-design-vue自定义使用阿里iconfont图标
  6. Spring Boot整合EhCache实现缓存操作.md
  7. javascript的执行机制
  8. Navicat连接mysql报1129错误
  9. MovePrevious和MoveNext的用法
  10. linux properties文件,读取Properties文件六种方法