一.简单爬取(无反爬虫)
1.爬取某网页中的单个图片
from urllib.request import urlopen
url = 'http://imgsrc.baidu.com/forum/w%3D580/sign=e23a670db9b7d0a27bc90495fbee760d/38292df5e0fe9925f33f62ef3fa85edf8db17159.jpg'
####该url地址为某张图片的链接
# 1. 获取图片的内容
content = urlopen(url).read()
# 2. 写入本地文件
with open('hello.jpg', 'wb') as f:
f.write(content)
2.爬取指定页贴吧的图片
import re
from urllib.request import urlopen
def get_content(url):
"""
获取网页内容
:param url:
:return:
"""
with urlopen(url) as html:
return html.read()
def parser_get_img_url(content):
"""
解析贴吧内容, 获取所有风景图片的url
:param content:
:return:
"""
pattern = r'<img class="BDE_Image".*?src="(http://.*?\.jpg)".*?>' ###加()后进行分组,输出的为url
imgUrl = re.findall(pattern, content.decode('utf-8').replace('\n', ' '))
return imgUrl
def main():
url = 'http://tieba.baidu.com/p/5437043553'
content = get_content(url)
imgLi = parser_get_img_url(content)
print(imgLi)
for index,imgurl in enumerate(imgLi):
# 根据图片的url获取每个图片的内容;
content = get_content(imgurl)
print(content)
with open('img/%s.jpg' %(index), 'wb') as f:
f.write(content)
print("第%s个图片下载成功...." %(index))
main()
这样就成功上爬取了图片。
二.反爬虫
有一些网站为了避免爬虫的恶意访问,会设置一些反爬虫机制,对方服务器会对爬虫进行屏蔽。常见的反爬虫机制主要有下面几个:-
通过分析用户请求的Headers信息进行反爬虫
-
通过检测用户行为进行反爬虫,比如通过判断同一个IP在短时间内是否频繁访问对应网站等进行分析
-
通过动态页面增加爬虫的爬取难度,达到反爬虫的目的
第一种反爬虫机制在目前网站中应用的最多,大部分反爬虫网站会对用户请求的Headers信息的“User-Agent”字段进行检测来判断身份,有时,这类反爬虫的网站还会对“Referer”字段进行检测。我们可以在爬虫中构造这些用户请求的Headers信息,以此将爬虫伪装成浏览器,简单的伪装只需设置好“User-Agent”字段的信息即可,如果要进行高相似度的伪装,则需要将用户请求的Headers信息中常见的字段都在爬虫中设置好
第二种反爬虫机制的网站,可以通过之前学习的使用代理服务器并经常切换代理服务器的方式,一般就能够攻克限制
1.伪装成浏览器
例:我们想爬取关于中国各种银行的一些信息,直接用一般的爬取会报错,我们再伪装成浏览器尝试。
url为:http://www.cbrc.gov.cn/chinese/jrjg/index.html
from urllib import request
from urllib.request import urlopen
url = "http://www.cbrc.gov.cn/chinese/jrjg/index.html"
# 如何伪装成浏览器访问?
# 1. 定义一个真实浏览器的代理名称
user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0"
# 2. 写到请求页面的header里面去
# request中有Request类,可以向其传入参数
req = request.Request(url,headers={'User-Agent': user_agent} )
# 3. 打开网页, 获取内容
print(urlopen(req).read().decode('utf-8'))
这样就成功爬到了相关信息。
当然在这里要说下,上面代码中的user_agent变量内容不是一成不变的,这要根据自己的电脑浏览器进行决定。
我在这里说出查看的方法。
1)进入要访问的url地址网页;
2)在空白处单击右键,再单击Inspect Element,
3)寻找Network选项,并双击更新后的第一行内容,我们便可以在Headers下的 Request headers下找到本地浏览器的User-Agent(注意:有的User-Agent比较长,我们要将其点开,复制全User-Agent)
常用 User-Agent
1.Android
Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19
Mozilla/5.0 (Linux; U; Android 4.0.4; en-gb; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Mozilla/5.0 (Linux; U; Android 2.2; en-gb; GT-P1000 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
2.Firefox
Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0
Mozilla/5.0 (Android; Mobile; rv:14.0) Gecko/14.0 Firefox/14.0
3.Google Chrome
Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36
Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19
4.iOS
Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3
2.使用IP代理
http://www.xicidaili.com/ (该网站中有很多代理ip可以供我们使用)
如何实现代理ip的使用?
1). 调用urllib.request.ProxyHandler(proxies=None); — 类似理解为Request对象
2). 调用Opener— 类似与urlopen, 这个是定制的
3). 安装Opener
4). 代理IP的选择
例:这里我们使用代理ip访问一个查看本地ip的网址
from urllib import request
url = 'https://www.whatismyip.com/'
###代理ip由 ’类型(http/https)‘:‘ip:端口号’组成
proxy = {'https':'218.14.115.211:3128'}
user_agent = 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0'
# 1).调用urllib.request.ProxyHandler(proxies=None); --- 类似理解为Request对象
proxy_support = request.ProxyHandler(proxy)
# 2).调用Opener - -- 类似与urlopen, 这个是定制的
opener = request.build_opener(proxy_support)
# 伪装浏览器
opener.addheaders = [('User-Agent',user_agent)]
# 3).安装Opener
request.install_opener(opener)
# 4).代理IP的选择
response = request.urlopen(url)
content = response.read().decode('utf-8')
print(content)
我使用的代理ip
我本地的真实ip信息
使用代理ip从网页中爬取的我的ip信息