crawler-05 网络爬虫实例

crawler-05 网络爬虫实例

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

  京东商品页面简单地使用get() 方法即可爬取;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests

def jd():
url="https://item.jd.com/29045327606.html"
try:
r=requests.get(url)
r.raise_for_status()
r.encoding=r.apparent_encoding
print(r.text[:1000]) #打印前1000个字符
except:
print("爬取失败")

def main():
jd()

if __name__ == '__main__':
main()

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

1、爬取报错503,爬取出错

1
2
3
4
5
6
7
8
9
10
11
12
>>> import requests
>>> url="https://www.amazon.cn/dp/B01HIUTCA8/ref=sr_1_1?pf_rd_i=1478512071&pf_rd_m=A1U5RCOVU0NYF2&pf_rd_p=c34ba49d-561d-46bc-8df5-4e0f8ddd3dc3&pf_rd_r=9X9CMNAKDR6GCBG1CZ8N&pf_rd_s=merchandised-search-top-1&pf_rd_t=101&qid=1576290684&s=gifts&sr=1-1"
>>> r=requests.get(url)
>>> r.status_code
503
>>> r.encoding
'ISO-8859-1'
>>> r.encoding=r.apparent_encoding
>>> r.text
···
<h4>请输入您在下方看到的字符</h4>\n <p class="a-last">抱歉,我们只是想确认一下当前访问者并非自动程序。为了达到最佳效果,请确保您浏览器上的
···

  可以看到r.text返回一些报错信息,这说明爬取出错并非网络问题,而是服务器做了网络爬虫限制;对网络爬虫限制,常见的如下:

1)来源审查:判断User‐Agent进行限制(技术层面限制)
  检查来访HTTP协议头的User‐Agent域,只响应浏览器或友好爬虫的访问;
2)发布公告:Robots协议(道德层面限制)
  告知所有爬虫网站的爬取策略,要求爬虫遵守;

  这里判断,可能是网站对User‐Agent进行了限制,下面进行验证。

2、查找出错原因

  网站一般只接受有浏览器发起的请求,而对于爬虫的请求可以拒绝;如下,通过查看请求r的头部信息的User-Agent字段,可以看到我们很实在地告知亚马逊我们是一个pyhon爬虫程序而不是浏览器,因此被拒绝导致出错。

1
2
3
>>> r.request.headers
{'User-Agent': 'python-requests/2.21.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
>>>

3、解决错误

  Mozilla/5.0是一个标准的浏览器身份标识字段,可能被识别为火狐、谷歌、IE10等;

1
2
3
4
5
6
7
8
>>> kv={'User-Agent': 'Mozilla/5.0'}
>>> 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]
'<!DOCTYPE html>\n<!--[if lt IE 7]> <html lang="zh-CN" class="a-no-js a-lt-ie9 a-lt-ie8 a-lt-ie7"> <![endif]-->\n<!--[if IE 7]> <html lang="zh-CN" class="a-no-js a-lt-ie9 a-lt-ie8"> <![endif]-->\n<!--[if IE 8]> <html lang="zh-CN" class="a-no-js a-lt-ie9"> <![endif]-->\n<!--[if gt IE 8]><!-->\n<html class="a-no-js" lang="zh-CN">

4、完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import requests

#亚马逊商品网页对爬虫做了简单的限制,
def amx():
url="https://www.amazon.cn/dp/B01HIUTCA8/ref=sr_1_1?pf_rd_i=1478512071&pf_rd_m=A1U5RCOVU0NYF2&pf_rd_p=c34ba49d-561d-46bc-8df5-4e0f8ddd3dc3&pf_rd_r=9X9CMNAKDR6GCBG1CZ8N&pf_rd_s=merchandised-search-top-1&pf_rd_t=101&qid=1576290684&s=gifts&sr=1-1"
kv={'User-agent':'Mozilla/5.0'}
try:
r=requests.get(url,headers=kv)
r.raise_for_status()
r.encoding=r.apparent_encoding
print(r.text[1000:2000])
except:
print("爬取失败")

def main():
amx()

if __name__ == '__main__':
main()

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

1、了解搜索引擎接口网址

1)百度的关键词接口: http://www.baidu.com/s?wd=keyword

2)360的关键词接口: http://www.so.com/s?q=keyword

3)如何得知接口网址:

  如下图,直接百度上搜”草莓“,结果可以看到网址栏“https://www.baidu.com/s?wd=草莓”的信息,从而可以知道百度关键词接口就是该格式。

UTOOLS1576466603678.png

2、IDLE上进行实操

  此处暂时不进行内容解析,只熟悉params参数和关键词接口的使用;360搜索的代码,只需要将wd改为q即可,其余一致。

1
2
3
4
5
6
7
8
9
10
>>> import requests
>>> kv={'wd':'草莓'}
>>> url="http://www.baidu.com/s"
>>> r=requests.get(url,params=kv)
>>> r.status_code
200
>>> r.request.url
>>> len(r.text)
1469
>>>

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

1、IDLE 实操

  打开文件路飞.jpeg,定义为文件标识符f,其中r.content表示返回内容的二进制形式,利用f.write可以写入文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> import requests
>>> url="https://c-ssl.duitang.com/uploads/item/201506/10/20150610095926_E5azR.thumb.700_0.jpeg"
>>> path="D:/路飞.jpeg"
>>> r=requests.get(url)
>>> r.status_code
200
>>> with open(path,'wb') as f:
f.write(r.content)


88916
>>> f.close()
>>>

2、完整代码

  异常处理很重要,要考虑周全,功能实现了,不算厉害,要从工程性角度去分析,代码如何执行都不会出错,才是稳定合格的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import requests
import os

def getPicture():
url = "https://c-ssl.duitang.com/uploads/item/201506/10/20150610095926_E5azR.thumb.700_0.jpeg"
root="D://pictures//"
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("爬取失败")

def main():
getPicture()

if __name__ == '__main__':
main()

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

1、首先获取接口url

1)类似之前百度搜索那样,直接在网站上输入ip进行查询;

2)如下图,可以看到查询出来的接口url是:

1
https://m.ip138.com/ip.asp?ip=

UTOOLS1576466665158.png

2、IDLE 实操

1
2
3
4
5
6
7
8
9
10
>>> import requests
>>> url="https://m.ip138.com/ip.asp?ip="
>>> ip="202.204.80.112"
>>> r=requests.get(url+ip)
>>> r.status_code
200
>>> r.text
···
您查询的IP:202.204.80.112</h1><p class="result">本站主数据:北京市海淀区 北京理工大学 教育网</p><p class="result">参考数据一:北京市 北京理工大学
···

3、完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests

def ipFrom():
url="https://m.ip138.com/ip.asp?ip="
ip = "202.204.80.112"
try:
r = requests.get(url + ip)
r.raise_for_status()
r.encoding=r.apparent_encoding
print(r.text)
except:
print("爬取失败")

def main():
ipFrom()

if __name__ == '__main__':
main()

总结

  以爬虫视角看待网络内容,静态页面爬取较简单,一切资源都可以看做url,只要将url构建出来,即可进行爬取。

附录

  五个实例所有完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import requests
import os
def jd():
url="https://item.jd.com/29045327606.html"
try:
r=requests.get(url)
r.raise_for_status()
r.encoding=r.apparent_encoding
print(r.text[:1000]) #打印前1000个字符
except:
print("爬取失败")

#亚马逊商品网页对爬虫做了简单的限制,
def amx():
url="https://www.amazon.cn/dp/B01HIUTCA8/ref=sr_1_1?pf_rd_i=1478512071&pf_rd_m=A1U5RCOVU0NYF2&pf_rd_p=c34ba49d-561d-46bc-8df5-4e0f8ddd3dc3&pf_rd_r=9X9CMNAKDR6GCBG1CZ8N&pf_rd_s=merchandised-search-top-1&pf_rd_t=101&qid=1576290684&s=gifts&sr=1-1"
kv={'User-agent':'Mozilla/5.0'}
try:
r=requests.get(url,headers=kv)
r.raise_for_status()
r.encoding=r.apparent_encoding
print(r.text[1000:2000])
except:
print("爬取失败")

def baidu():
url="http://www.baidu.com/s"
kv={'wd':'草莓'}
try:
r = requests.get(url, params=kv)
print(r.request.url)
r.raise_for_status()
print(len(r.text))
except:
print("爬取失败")

def so360():
url=" http://www.so.com/s"
kv={'q':'草莓'}
try:
r = requests.get(url, params=kv)
print(r.request.url)
r.raise_for_status()
print(len(r.text))
except:
print("爬取失败")

def getPicture():
url = "https://c-ssl.duitang.com/uploads/item/201506/10/20150610095926_E5azR.thumb.700_0.jpeg"
root="D://pictures//"
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("爬取失败")

def ipFrom():
url="https://m.ip138.com/ip.asp?ip="
ip = "202.204.80.112"
try:
r = requests.get(url + ip)
r.raise_for_status()
r.encoding=r.apparent_encoding
print(r.text)
except:
print("爬取失败")

def main():
#jd()
#amx()
#baidu()
#so360()
#getPicture()
ipFrom()

if __name__ == '__main__':
main()
欢迎打赏,谢谢
------ 本文结束------
0%