文章截图均来自中国大学mooc Python网络爬虫与信息提取的教程,以上仅作为我的个人学习笔记。
实例1:京东商品页面爬取
import requests
url = "https://item.jd.com/2967929.html"
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = r.apparent_encoding
print(r.text[:1000])
except:
print("爬取失败")
这个代码失效了(应该是反爬加强了),我的爬取结果如下(貌似是需要登录信息),以后学会了再来补充:
<script>window.location.href='https://passport.jd.com/uc/login?ReturnUrl=http://item.jd.com/2967929.html'</script>
实例2:亚马逊商品页面爬取
>>> import requests
>>> r = requests.get("https://www.amazon.cn/gp/product/B01M8L5Z3Y")
>>> r.status_code
200
>>> r.encoding
'UTF-8'
>>> r.text
'\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
总结以上两点:事实上服务器返回了相关信息,那么就不是网络问题,实例2是返回的数据量太大IDLE会失效。
回顾反网络爬虫的方法:
- Robots协议
- 比较隐性:通过判断对网站访问的http的头来查看你的访问是不是由一个爬虫引起的,网站一般接受的是由浏览器产生的http请求,但是对于爬虫引起的,是可以拒绝的。(也就是来源审查)
我们可以对于发给亚马逊服务器的request对象的头部查看(说明我们的爬虫忠实的告知了服务器)
>>> r.request.headers
{'User-Agent': 'python-requests/2.23.0', 'Accept-Encoding': 'gzip, deflate',
'Accept': '*/*', 'Connection': 'keep-alive'}
但是我们学习Request库的时候知道可以更改头部信息。
>>> kv = {'user-agent':'Mozilla/5.0'}
>>> r.request.headers
{'User-Agent': 'python-requests/2.23.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
>>> url = "https://www.amazon.cn/gp/product/B01M8L5Z3Y"
>>> r = requests.get(url,headers = kv)
>>> r.request.headers
{'user-agent': 'Mozilla/5.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
>>> r.text[:1000]
<!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=\'VE22CWK4HZKT5HB9MBW5\',\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(){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.stu'
>>>
同样对于京东商品的操作也是一样。
import requests
url = "https://item.jd.hk/100001553181.html"
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])
except:
print("爬取失败")
爬取结果
====================== RESTART: E:\py_test\jd商品信息爬取.py ======================
<!DOCTYPE html>
<html lang="zh-CN" class="root61">
<head>
<!-- worldbuy new -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>【VANSVN000D3HY28】VANS(万斯)低帮情侣板鞋 黑白 VansOld Skool VN000D3HY28 黑色 36【行情 报价 价格 评测】-京东</title>
<meta name="keywords" content="VANSVN000D3HY28,VANSVN000D3HY28,VANSVN000D3HY28报价,VANSVN000D3HY28报价"/>
<meta name="description" content="【VANSVN000D3HY28】京东JD.COM提供VANSVN000D3HY28正品行货,并包括VANSVN000D3HY28网购指南,以及VANSVN000D3HY28图片、VN000D3HY28参数、VN000D3HY28评论、VN000D3HY28心得、VN000D3HY28技巧等信息,网购VANSVN000D3HY28上京东,放心又轻松" />
<meta name="format-detection" content="telephone=no">
<meta http-equiv="mobile-agent" content="format=xhtml; url=//item.m.jd.com/product/100001553181.html">
<meta http-equiv="mobile-agent" content="format=html5; url=//item.m.jd.com/product/100001553181.html">
<link rel="canonical" href="//item.jd.com/100001553181.html"/>
<link rel="dns-prefetch" href="//misc.360buyimg.com"/>
<link rel=
>>>
案例3:百度/360搜索关键词提交
无论是百度还是360他们都对搜索提供了一个接口。
事实上我们只需要构建这样的Url就可以实现对于关键词的提取,之前我们学过params,他可以向url中增加相关的内容。
###百度
import requests
try:
kv = {'wd':'java'}
r = requests.get('http://www.baidu.com/s',params=kv)
r.raise_for_status()
print(len(r.text))
except:
print("发生异常")
###结果
======================= RESTART: E:/py_test/百度关键词提取.py =======================
1519
>>>
###360
import requests
try:
kv = {'q':'java'}
r = requests.get('http://www.so.com/s',params=kv)
r.raise_for_status()
print(len(r.text))
except:
print("发生异常")
###结果
======================= RESTART: E:/py_test/360关键词.py =======================
225602
>>>
实例4:网络图片的爬取
图片是二进制格式,怎么保存为文件?
- 首先打开文件:就是我们要存储的abc.jpg
- 并且把他定义为一个文件标识符f
- 然后将返回的内容写道这个文件中(response对象返回的内容中 content表示的是二进制的)
>>> import requests
>>> path = "D:/abc.jpg"
>>> url = "http://img-arch.pconline.com.cn/images/upload/upc/tx/photoblog/1309/22/c46/26150170_1379859737352.jpg"
>>> r = requests.get(url)
>>> r.status_code
200
>>> with open(path,'wb') as f:
f.write(r.content)
240071
>>>
怎么将文件本身的名称保存下来呢?需要用到os库。
#爬取图片
import requests
import os
url = "http://img-arch.pconline.com.cn/images/upload/upc/tx/photoblog/1309/22/c46/26150170_1379859737352.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("爬取失败")
###结果
======================= RESTART: E:/py_test/图片原名爬取.py =======================
文件保存成功
>>>
视频爬取:
#爬取视频—驯龙高手
import requests
import os
url = "http://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4"
root = "D://video//"
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("爬取失败")
###结果
======================== RESTART: E:/py_test/视频爬取.py ========================
视频保存成功
>>>
实例5:IP地址归属地的自动查询(通过IP138的网站提供的功能进行查找)
- 如何查看一个IP地址是来源于北京还是上海,还是美国呢?
- 当然,要先判断一个地址的归属地必须要有一个库,但是我们的程序没有这个库,所以需要在网上查找对应的资源
>>> import requests
>>> url = "https://www.ip38.com/ip.php?ip="
>>> r = requests.get(url+'223.104.147.30')
>>> r.status_code
200
>>> r.text
'<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv=Content-Type content="text/html......
单元小结:
以爬虫的角度看待网络内容