python网络爬虫及信息提取(基础)

python网络爬虫(基础)

requests库
通用框架
BeautifulSoup库
HTML的遍历
信息标记
信息提取的一般方法
实例:
1.京东商品页面的爬取
2.亚马逊商品页面的爬取
3.百度/360搜索关键词提交
4.网络图片的爬取和存储
5.IP地址归属地的自动查询
6.“中国大学排名定向爬虫”实例

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

Respose对象的属性

r.status_code HTTP请求的返回状态,200表示连接成功,404表示失败
r.txt HTTP响应内容的字符串形式,即,url对应的页面内容
r.encoding 从HTTP header 中猜测的响应内容编码方式
r.apparent_encoding 从内容中分析的响应内容的编码方式(备选编码方式)
r.content HTTP响应内容的二进制形式

通用框架:
import  requests

def getHTMLText(url):
    try:
        r = requests.get(url ,timeout = 30)
        r.raise_for_status() #如果状态不是200,引发HTTPError异常
        r.encoding = r.apparent_encoding #转化为utf-8
        return r.text
    except:
        return "产生异常"

if __name__ == "__main__":
    url = "http://www.baidu.com"
    print(getHTMLText(url))

实例:

1.京东商品页面的爬取

首先获取网页连接
https://krisborg.jd.com/
在这里插入图片描述

import  requests
url = "https://krisborg.jd.com/"
try:
    r =  requests.get(url)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    print(r.text[:1000])
except:
    print("爬取失败")

结果:

<!--jd默认浏览-->
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <!--JA统计-->
    <script>var jdpts=new Object();jdpts._st=new Date().getTime();</script>
    <meta content="克里斯·博格旗舰店,提供克里斯·博格旗舰店各类正品商品的报价、促销、评论、导购、图片等信息,欢迎您再次光顾克里斯·博格旗舰店" name="description">
    <meta content="克里斯·博格旗舰店、,服饰内衣、京东" name="keywords">
    <title>
        			克里斯·博格旗舰店 - 京东
	    </title>
    <link rel="icon" href="//www.jd.com/favicon.ico" mce_href="//www.jd.com/favicon.ico" type="image/x-icon">
    
    <!-- LESS -->
    
    <!-- 新布局样式-->
    <link rel="stylesheet" href="//static.360buyimg.com/static-shop-sale-p/libs/normalize-css/normalize.css">
    <link rel="stylesheet" href="//static.360buyimg.com/static-shop-sale-p/css/common/layout.css">
    <!-- 头部公用 -->
    <link rel="stylesheet" type="text/css" href="//static.360buyimg.com/static-shop-sale-p/css/prev-versi
2.亚马逊商品页面的爬取

https://www.amazon.cn/dp/B01ION3VWI/ref=sr_1_1?__mk_zh_CN=亚马逊网站&keywords=python&qid=1562862762&s=gateway&sr=8-1
在这里插入图片描述

import  requests

url = "https://www.amazon.cn/dp/B01ION3VWI/ref=sr_1_1?__mk_zh_CN=%E4%BA%9A%E9%A9%AC%E9%80%8A%E7%BD%91%E7%AB%99&keywords=python&qid=1562862762&s=gateway&sr=8-1"
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[1000:2000])
except:
    print("爬取失败")

结果:

(function(d,e){function h(f,b){if(!(a.ec>a.mxe)&&f){a.ter.push(f);b=b||{};var c=f.logLevel||b.logLevel;c&&c!==k&&c!==m&&c!==n&&c!==p||a.ec++;c&&c!=k||a.ecf++;b.pageURL=""+(e.location?e.location.href:"");b.logLevel=c;b.attribution=f.attribution||b.attribution;a.erl.push({ex:f,info:b})}}function l(a,b,c,e,g){d.ueLogError({m:a,f:b,l:c,c:""+e,err:g,fromOnError:1,args:arguments},g?{attribution:g.attribution,logLevel:g.logLevel}:void 0);return!1}var k="FATAL",m="ERROR",n="WARN",p="DOWNGRADED",a={ec:0,ecf:0,
pec:0,ts:0,erl:[],ter:[],mxe:50,startTimer:function(){a.ts++;setInterval(function(){d.ue&&a.pec<a.ec&&d.uex("at");a.pec=a.ec},1E4)}};l.skipTrace=1;h.skipTrace=1;h.isStub=1;d.ueLogError=h;d.ue_err=a;e.onerror=l})(ue_csm,window);
ue.stub(ue,"event");ue.stub(ue,"onSushiUnload");ue.stub(ue,"onSushiFlush");
var ue_url='/gp/product/B01ION3VWI/uedata/unsticky/459-2984941-1170265/NoPageType/ntpoffrw',
ue_sid='459-2984941-1170265',
ue_mid='AAH
3.百度/360搜索关键词提交
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("爬取失败")

结果:
455467

4.网络图片的爬取和存储

http://img.redocn.com/sheji/20160823/beijingqiangmenghuansenlinbeijingfengjingtupianJPGgeshixiazai_6974943_small.jpg
在这里插入图片描述

import  requests
import os
url = "http://img.redocn.com/sheji/20160823/beijingqiangmenghuansenlinbeijingfengjingtupianJPGgeshixiazai_6974943_small.jpg"
root = "D://pic//"
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("文件保存成功")
    else:
        print("文件保存失败")
except:
    print("爬取失败")

在这里插入图片描述
成功保存。

5.IP地址归属地的自动查询
import  requests

url = "http://m.ip138.com/ip.asp?ip="
try:
    r = requests.get(url+'55.55.55.55')
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    print(r.text[-500:])
except:
    print("读取失败")

结果:
在这里插入图片描述

BeautifulSoup库

使用方法:

from bs4 import BeautifulSoup
soup = BeautifulSoup('<p>data</p>','html.parser')
html的基本内容
<html>
	<body>
			<p class="title"> ... </p>
	</body>
</html>

<>为标签,整个为标签树

<p class="title">...</p>

<p>…<p>:标签 Tag
p标签NAME成对出现
class=“title”属性
可以通过打开文件提供html内容

soup = BeautifulSoup(open("D://demo.html"),"html.parser")
Beautiful Soup类的基本元素

Tag 标签,最基本的信息组织单元,分别用<>和</>表明开头和结尾
Name 标签的名字,<p>…<\p>的名字是‘p’,格式是<tag>.name
Arrtibutes 标签的属性。字典形式组织,格式:<tag>.attrs
NavigableString 标签内的非属性字符串,<>…</>中字符串,格式:<tag>.string
Comment 标签内字符串的注释部分,一种特殊的Comment类型

import  requests

r = requests.get("http://python123.io/ws/demo.html")
demo = r.text

用requests库获取html的内容

我们可以到这个网页去看这个网页的源代码。
在这里插入图片描述

HTML的遍历

在这里插入图片描述

下行遍历:

.contents 子节点的列表,将<tag>所有儿子节点存入列表
.children 子节点的迭代类型,与.contents类似,用于循环遍历儿子节点
.desendants 子孙节点的迭代类型,包含所有的子孙节点,用于循环遍历
遍历儿子节点

for child in soup.body.children:
	print(child)
上行遍历:

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

import requests
from bs4 import BeautifulSoup
r = requests.get("http://python123.io/ws/demo.html")
demo = r.text
soup = BeautifulSoup(demo , "html.parser")
for parent in soup.a.parents:
	 if parent is None:
			print(parent)
	 else:
			print(parent.name)

结果:

p
body
html
[document]
平行遍历:

.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)	
如何让<html>内容更加友好的显示?

.prettify()会自动添加换行符

print(soup..prettify())

即可得到

<html>
 <head>
  <title>
   This is a python demo page
  </title>
 </head>
 <body>
 ......

信息标记

XML

三种格式:
1.<name>…
2.<name />
3.<!-- -->

JSON

三种格式:
1.“key” : “value”
2.“key” : [“value1”,“value2”]
3.“key” : {“subkey”,“subvalue”}

YAML

三种格式:
1.key : value
2.key : #Comment
-value1
-value2
3.key :
subkey : subvalue

信息提取的一般方法

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

实例:

提取HTML中的所有URL连接
思路:
1)搜索到所有<a>标签
2)解析<a>标签格式,提取href后的连接内容

import requests
from bs4 import BeautifulSoup
r = requests.get("http://python123.io/ws/demo.html")
demo = r.text
soup = BeautifulSoup(demo , "html.parser")
for link in soup.find_all('a'):
    print(link.get('herf'))
<>.find_all(name,attrs,recursive,string,**kwargs) 
返回一个列表类型,存储查找的结果。
name:对标签名称的检索字符串
attrs:对标签属性值的检索字符串,可标注属性检索
recursive:是否对子孙全部检索,默认True
string:<>...</>中字符串区域的检索字符串

可用下面的代码来查看所有’a’标签的内容

for link in soup.find_all('a'):
    print(link.get('herf'))

可用下面的代码来查看所有标签

for tag in soup.find_all(True):
    print(tag.name)

实例:

6.“中国大学排名定向爬虫”实例

http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html

http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html   2019年的
http://www.zuihaodaxue.cn/zuihaodaxuepaiming2018.html   2018年的
http://www.zuihaodaxue.cn/zuihaodaxuepaiming2017.html   2017年的
http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html   2016年的

功能描述:
输入:大学排名URL连接
输出:大学排名信息的屏幕输出(排名,大学名称,省份,总分)
技术路线: requests-bs4
定向爬虫:仅对输入URL进行爬取,不扩展爬取。

程序的结构设计
步骤1:从网页获取大学排名网页内容
getHTMLText()
步骤2:提取网页内容中信息到合适的数据结构
fillUnivList()
步骤3:利用数据结构展示并输出结果
printUnivList()

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
所有大学的信息都在 tbody 标签下 , 每一个大学的信息标签都在tr 标签下 , 排名, 学校名称, 分数等 在td 标签下

所有大学的信息被封装在一个表格中tbody
每一个大学的信息被封装在一个标签中tr
每个tr中的信息又被td标签所包围

代码:

import requests
from bs4 import BeautifulSoup
import bs4


def getHTMLText(url):
    # 获取html的所有信息
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        print("异常")


def fillUnivList(ulist, html):
    # 提取html中的关键信息加到ulist中
    soup = BeautifulSoup(html, 'html.parser')  # 解析
    # 首先找到tbody ,找到所有大学的相关信息
    for tr in soup.find('tbody').children:
        # 遍历tbody的孩子标签,就是
        if isinstance(tr, bs4.element.Tag):
            # 过滤tr的类型
            tds = tr('td')  # 所有的td标签
            ulist.append([tds[0].string, tds[1].string, tds[2].string, tds[3].string])
            # tds[0] 是排名 , tds[1] 是学校名称 , tds[2] 是省份  ,tds[3] 是总分


def printUniveList(ulist, num):
    # 格式化输出 chr12288  中文填充
    tplt = "{0:^10}\t{1:{4}^10}\t{2:{5}^10}\t{3:^10}"  # {4},{5}表示用第三种方式填充
    print(tplt.format("排名", "学校名称", "省份", "总分", chr(12288), chr(12288)))
    for i in range(num):
        u = ulist[i]
        print(tplt.format(u[0], u[1], u[2], u[3], chr(12288), chr(12288)))


def tranUrl(urls):
    # 爬取近年的数据
    n = 2016
    u = "http://www.zuihaodaxue.cn/zuihaodaxuepaiming"
    for i in range(4):
        url = u + str(n + i) + ".html"
        urls.append(url)


def main():
    urls = []
    tranUrl(urls)
    for i in range(len(urls)):
        try:
            print("%s 大学排名" % urls[i][-9:-5])
            uinfo = []
            html = getHTMLText(urls[i])
            fillUnivList(uinfo, html)
            printUniveList(uinfo, 15)
        except:
            continue


main()

结果:

2016 大学排名
    排名    	   学校名称   	    省份    	    总分    
    1     	   清华大学   	   北京市    	   95.9   
    2     	   北京大学   	   北京市    	   82.6   
    3     	   浙江大学   	   浙江省    	    80    
    4     	  上海交通大学  	   上海市    	   78.7   
    5     	   复旦大学   	   上海市    	   70.9   
    6     	   南京大学   	   江苏省    	   66.1   
    7     	 中国科学技术大学 	   安徽省    	   65.5   
    8     	 哈尔滨工业大学  	   黑龙江省   	   63.5   
    9     	  华中科技大学  	   湖北省    	   62.9   
    10    	   中山大学   	   广东省    	   62.1   
    11    	   东南大学   	   江苏省    	   61.4   
    12    	   天津大学   	   天津市    	   60.8   
    13    	   同济大学   	   上海市    	   59.8   
    14    	 北京航空航天大学 	   北京市    	   59.6   
    15    	   四川大学   	   四川省    	   59.4   
2017 大学排名
    排名    	   学校名称   	    省份    	    总分    
2018 大学排名
    排名    	   学校名称   	    省份    	    总分    
    1     	   清华大学   	    北京    	   95.3   
    2     	   北京大学   	    北京    	   78.6   
    3     	   浙江大学   	    浙江    	   73.9   
    4     	  上海交通大学  	    上海    	   73.1   
    5     	   复旦大学   	    上海    	   66.0   
    6     	 中国科学技术大学 	    安徽    	   61.9   
    7     	   南京大学   	    江苏    	   59.8   
    8     	  华中科技大学  	    湖北    	   59.1   
    9     	   中山大学   	    广东    	   58.6   
    10    	 哈尔滨工业大学  	   黑龙江    	   57.4   
    11    	   同济大学   	    上海    	   56.4   
    12    	   武汉大学   	    湖北    	   55.5   
    13    	   东南大学   	    江苏    	   55.3   
    14    	  西安交通大学  	    陕西    	   54.2   
    15    	 北京航空航天大学 	    北京    	   54.0   
2019 大学排名
    排名    	   学校名称   	    省份    	    总分    
    1     	   清华大学   	    北京    	   94.6   
    2     	   北京大学   	    北京    	   76.5   
    3     	   浙江大学   	    浙江    	   72.9   
    4     	  上海交通大学  	    上海    	   72.1   
    5     	   复旦大学   	    上海    	   65.6   
    6     	 中国科学技术大学 	    安徽    	   60.9   
    7     	  华中科技大学  	    湖北    	   58.9   
    7     	   南京大学   	    江苏    	   58.9   
    9     	   中山大学   	    广东    	   58.2   
    10    	 哈尔滨工业大学  	   黑龙江    	   56.7   
    11    	 北京航空航天大学 	    北京    	   56.3   
    12    	   武汉大学   	    湖北    	   56.2   
    13    	   同济大学   	    上海    	   55.7   
    14    	  西安交通大学  	    陕西    	   55.0   
    15    	   四川大学   	    四川    	   54.4   
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值