mooc课程地址:
https://www.icourse163.org/learn/BIT-1001870001?tid=1003245012#/learn/announce
一、爬虫
1、网络爬虫的尺寸
规模 | 小规模,数据量小 | 中规模,数据规模较大 | 大规模,搜索引擎 |
---|---|---|---|
爬取速度敏感程度 | 不敏感 | 敏感 | 爬取速度关键 |
常用库 | Requests库 | Scrapy库 | 定制开发 |
适用范围 | 爬取网页玩转网页 | 爬取网站爬取系列网站 | 爬取全网 |
2、Requests库
(1)下载
cmd直接使用pip下载Requests库: 速度时常在20KB以内
pip install requests
使用国内镜像:
注意:新版ubuntu要求使用https源
清华:https://pypi.tuna.tsinghua.edu.cn/simple
阿里云:http://mirrors.aliyun.com/pypi/simple/
中国科技大学:https://pypi.mirrors.ustc.edu.cn/simple/
华中理工大学:http://pypi.hustunique.com/
山东理工大学:http://pypi.sdutlinux.org/
豆瓣:http://pypi.douban.com/simple/
pip install -i http://pypi.douban.com/simple/ requests
(2)使用
①通用代码框架
import requests
def getHTMLText(url):
try :
r = requests . get (ur1, timeout= =30)
r. raise for status () #如果状态不是200, 引发HTTPError异常
r. encoding = r. apparent_ encoding
return r. text
except :
return "产生异常"
if _name_ == "_main_";
ur1 = "http: / /www . baidu. com"
print (getHTMLText (ur1) )
②Requests库的7个主要方法
方法 | 说明 |
---|---|
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. request (method, url, **kwargs)
●method : 请求方式,对应get/put/post等7种
●url:拟获取页面的ur1链接
● **kwargs: 控制访问的参数,共13个
二、robots协议
由于网站信息涉密或涉及用户个人信息等,或访问时可能会对服务器造成资源影响,我们在爬取网站信息时,需要遵守robots协议。
示例(京东的robots协议):https://www.jd.com/robots.txt
#不允许访问内容
#注释:*代表所有,/代表根目录
User-agent: *
Disallow: /?*
Disallow: /pop/*.html
Disallow: /pinpai/*.html?*
#恶意爬虫
User-agent: EtaoSpider
Disallow: /
User-agent: HuihuiSpider
Disallow: /
User-agent: GwdangSpider
Disallow: /
User-agent: WochachaSpider
Disallow: /
Robots协议的使用
网络爬虫:自动或人工识别robots.txt,再进行内容爬取。
约束性: Robots协议是建议但非约束性,网络爬虫可以不遵守,但存在法律风险。
对Robots协议的理解:
访问量很小:可以遵守 访问量较大:建议遵守 | 非商业且偶尔:建议遵守 商业利益:必须遵守 | 必须遵守 |
---|---|---|
爬取网页 玩转网页 | 爬取网站爬取系列网站 | 爬取全网 |
特别的,当程序较小,每天只访问服务器几次,与人类的访问行为十分类似(即类人行为),对服务器不会造成巨大的资源影响时,可不参考robots协议,但要注意所爬取的资源不能作为商用。
三、实例
1、京东商品页面爬取
直接在idle中进行操作
#加载requests库
import requests
#复制京东商品链接(以华为Mate20Pro为例),利用get方法获取链接内容
r = requests.get("https://item.jd.com/100000986034.html")
r.status_code #返回状态码
>>>200
r.encoding #返回编码
>>>'gbk'
r.text[:1000] #查看返回内容
>>>'<!DOCTYPE HTML>\n<html lang="zh-CN">\n<head>\n <!-- shouji -->\n <meta http-equiv="Content-Type" content="text/html; charset=gbk" />\n <title>【华为Mate 20 Pro】华为 HUAWEI Mate 20 Pro 麒麟980芯片全面屏超微距影像超大广角徕卡三摄6GB+128GB翡冷翠全网通版双4G手机【行情 报价 价格 评测】-京东</title>\n <meta name="keywords" content="HUAWEIMate 20 Pro,华为Mate 20 Pro,华为Mate 20 Pro报价,HUAWEIMate 20 Pro报价"/>\n <meta name="description" content="【华为Mate 20 Pro】京东JD.COM提供华为Mate 20 Pro正品行货,并包括HUAWEIMate 20 Pro网购指南,以及华为Mate 20 Pro图片、Mate 20 Pro参数、Mate 20 Pro评论、Mate 20 Pro心得、Mate 20 Pro技巧等信息,网购华为Mate 20 Pro上京东,放心又轻松" />\n <meta name="format-detection" content="telephone=no">\n <meta http-equiv="mobile-agent" content="format=xhtml; url=//item.m.jd.com/product/100000986034.html">\n <meta http-equiv="mobile-agent" content="format=html5; url=//item.m.jd.com/product/100000986034.html">\n <meta http-equiv="X-UA-Compatible" content="IE=Edge">\n <link rel="canonical" href="//item.jd.com/100000986034.html"/>\n <link rel="dns-prefetch"'
全代码
import requests
ur1 = "https://item.jd.com/100000986034.html."
try :
r = requests.get (ur1)
r.raise_for_status ()
r.encoding = r . apparent_ encoding
print (r. text[:1000] )
except :
print("爬取失败")
2、亚马逊商品页面爬取
(重点:通过headers字段让代码模拟浏览器向亚马逊提出http请求)
直接在idle中进行操作
import requests
r.request.headers #查看访问请求
>>>{'User-Agent': 'python-requests/2.21.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
kv = {'user-agent':'Mozilla/5.0'}
url = "https://www.amazon.cn/dp/B07JW1TLQS/ref=sr_1_4?s=wireless&ie=UTF8&qid=1551188400&sr=1-4&keywords=%E5%8D%8E%E4%B8%BA"
r = requests.get(url, headers = kv)
r.status_code
>>>200
r.request.headers
>>>{'user-agent': 'Mozilla/5.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
r.text[:1000]
>>>'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n <!doctype html><html class="a-no-js" data-19ax5a9jf="dingo">\n <head>\n<script type="text/javascript">var ue_t0=ue_t0||+new Date();</script>\n<script type="text/javascript">\nwindow.ue_ihb = (window.ue_ihb || window.ueinit || 0) + 1;\nif (window.ue_ihb === 1) {\nvar ue_hob=+new Date();\nvar ue_id=\'DWY5YT83K9DTYVCN05XY\',\nue_csm = window,\nue_err_chan = \'jserr-rw\',\nue = {};\n(function(d){var e=d.ue=d.ue||{},f=Date.now||function(){return+new Date};e.d=function(b){return f()-(b?0:d.ue_t0)};e.stub=function(b,a){if(!b[a]){var c=[];b[a]=function(){c.push([c.slice.call(arguments),e.d(),d.ue_id])};b[a].replay=function(b){for(var a;a=c.shift();)b(a[0],a[1],a[2])};b[a].isStub=1}};e.exec=function(b,a){return function(){if(1==window.ueinit)try{return b.apply(this,arguments)}catch(c){ueLogError(c,{attribution:a||"undefined",logLevel:"WARN"})}}}})(ue_csm);\n\nue.stub(ue,"log");ue.stub(ue,"onunload");ue.stub(ue,"onflush");\n'
全代码
import requests
url = "https: / /www . amazon . cn/ gp/product/B01M8L5Z3Y"
try:
kv = f 'user-agent' : 'Mozilla/5.0']
r = requests .get (ur1 , headers=kv)
r. raise for status ()
r. encoding = r . apparent encoding
print (r. text [1000:2000] )
except :
print ("爬取失败")
3、百度/360搜索关键字提交
直接在idle中进行操作
import requests
#参数params向url中增加内容,Python为关键词
kv = {'wd' : 'Python'}
r = requests.get("http://www.baidu.com/s", params = kv)
r.status_code
>>>200
r.request.url
>>>'http://www.baidu.com/s?wd=Python'
len(r.text)
>>>446865
全代码
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、网络图片的爬取和存储
直接在idle中进行操作
import requests
path = "D:/abc.jpg"
url = "http://image.nationalgeographic.com.cn/2017/0211/20170211061910157.jpg"
r = requests.get(url)
r.status_code
>>>200
with open(path,'wb') as f:
f.write(r.content)
>>>228206
f.close()
全代码
import requests
import os
url = "http:// image . nationalgeographic. com . cn/2017/0211/20170211061910157.jpg"
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("文件保存成功")
else :
print("文件已存在")
except :
print("爬取失败")
5、IP地址归属地的自动查询
直接在idle中进行操作
import requests
url = "http://m.ip138.com/ip.asp?ip="
r = requests.get(url + '202.204.80.112')
r.status_code
>>>200
r.text[-500:]
'value="查询" class="form-btn" />\r\n\t\t\t\t\t</form>\r\n\t\t\t\t</div>\r\n\t\t\t\t<div class="query-hd">ip138.com IP查询(搜索IP地址的地理位置)</div>\r\n\t\t\t\t<h1 class="query">您查询的IP:202.204.80.112</h1><p class="result">本站主数据:北京市海淀区 北京理工大学 教育网</p><p class="result">参考数据一:北京市 北京理工大学</p>\r\n\r\n\t\t\t</div>\r\n\t\t</div>\r\n\r\n\t\t<div class="footer">\r\n\t\t\t<a href="http://www.miitbeian.gov.cn/" rel="nofollow" target="_blank">沪ICP备10013467号-1</a>\r\n\t\t</div>\r\n\t</div>\r\n\r\n\t<script type="text/javascript" src="/script/common.js"></script></body>\r\n</html>\r\n'