1. 什么是爬虫
在互联网上一直爬行的蜘蛛, 如果遇到需要的资源, 那么它就会抓取下来(html内容);模拟浏览器快速
访问页面的内容.
2. 爬虫的实现步骤
- 分析需要获取的信息在网页源码中的规律
- 获取网页源码
- 解析页面内容
- 获取所需要的信息
示例:爬取百度贴吧图片
'''
url规律:
https://tieba.baidu.com/p/5752826839?pn=1
https://tieba.baidu.com/p/5752826839?pn=2
https://tieba.baidu.com/p/5752826839?pn=3
图片html分析:
<img class="BDE_Image" src="https://imgsa.baidu.com/forum/
w%3D580/sign=8be466fee7f81a4c2632ecc1e7286029/bcbb0d338744ebf
89d9bb0b5d5f9d72a6259a7aa.jpg" size="350738" changedsize="true"
width="560" height="995">
<img class="BDE_Image" src="https://imgsa.baidu.com/forum/
w%3D580/sign=64e6bdda38a85edffa8cfe2b795609d8/4efebd315c60
34a886086c0bc71349540b2376aa.jpg" size="286672" changedsize
="true" width="560" height="995">
'''
# 用于获取网页内容
from urllib.request import urlopen
# 用于捕获异常
from urllib.error import URLError
#用于分析网页内容及获取需要的信息
import re
def get_page(url):
# 获取页面内容
try:
urlObj = urlopen(url)
except URLError as e:
print("爬取%s失败...." % (url))
else:
# 默认是bytes类型, 需要的是字符串, 二进制文件不能decode
content = urlObj.read()
return content
def parser_content(content):
# 解析页面内容, 获取所有的图片链接
content = content.decode('utf-8').replace('\n', ' ')
pattern = re.compile(r'<img class="BDE_Image".*? src="(https://.*?\.jpg)".*?">')
imgList = re.findall(pattern, content)
return imgList
def get_page_img(page):
url = "https://tieba.baidu.com/p/5752826839?pn=%s" %(page)
content = get_page(url)
print(content)
if content:
imgList = parser_content(content)
for imgUrl in imgList:
# 依次遍历图片的每一个链接, 获取图片的内容;
imgContent = get_page(imgUrl)
imgName = imgUrl.split('/')[-1]
with open('img/%s' %(imgName), 'wb') as f:
f.write(imgContent)
print("下载图片%s成功...." %(imgName))
if __name__ == '__main__':
for page in range(1, 11):
print("正在爬取第%s页的图片...." %(page))
get_page_img(page)
3. 反爬虫的常用方法
3.1 模拟浏览器:
reqObj.add_header('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
3.2 设置代理IP:
3.2.1 获取代理IP:https://www.xicidaili.com/ (西刺代理网站提供)
3.2.2 使用代理IP爬取网页内容:
from urllib.request import ProxyHandler, build_opener, install_opener, urlopen
def use_proxy(proxies, url):
# 1. 调用urllib.request.ProxyHandler
proxy_support = ProxyHandler(proxies=proxies)
# 2. Opener 类似于urlopen
opener = build_opener(proxy_support)
# 3. 安装Opener
install_opener(opener)
# user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0"
# user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0"
user_agent = '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'
# 模拟浏览器;
opener.addheaders = [('User-agent', user_agent)]
urlObj = urlopen(url)
content = urlObj.read().decode('utf-8')
return content
if __name__ == '__main__':
url = 'http://httpbin.org/get'
proxies = {'https': "111.177.178.167:9999", 'http': '114.249.118.221:9000'}
use_proxy(proxies, url)
3.3 设置download_delay:
作用:设置下载的等待时间,大规模集中的访问对服务器的影响最大,相当与短时间中增大服务器负载。
缺点: 下载等待时间长,不能满足段时间大规模抓取的要求,太短则大大增加了被ban的几率
3.4 禁止cookies:
Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session
跟踪而储存在用户本地终端上的数据(通常经过加密)。
作用: 禁止cookies也就防止了可能使用cookies识别爬虫轨迹的网站得逞。
实现: COOKIES_ENABLES=False
3.5 分布式爬虫Scrapy+Redis+MySQL:
Scrapy-Redis是一个基于Redis的Scrapy分布式组件。它利用Redis对用于爬取的请求(Requests)进
行存储和调度(Schedule),并对爬取产生rapy一些比较关键的代码,将scrapy变成一个可以在多个主
机上同时运行的分布式爬虫。
4. 保存cookie信息
4.1 什么是cookie信息:
某些网站为了辨别用户身份, 只有登陆某个页面才可以访问;
登陆信息保存方式: 进行一个会话跟踪(session),将用户的相关信息保存到本地的浏览器中;
4.2 cookie信息的使用:
4.2.1 引入第三方模块:
from urllib.parse import urlencode
from urllib.request import HTTPCookieProcessor
from http import cookiejar
from urllib import request
4.2.2 获取cookie信息并保存到变量中:
1). 声明一个类, 将cookie信息保存到变量中;
cookie = cookiejar.CookieJar()
2). 通过urllib.request的 HTTPCookieProcessor创建cookie请求器;
handler = HTTPCookieProcessor(cookie)
3). 通过处理器创建opener; ==== urlopen
opener = request.build_opener(handler)
4). 打开url页面
response = opener.open('http://www.baidu.com')
print(cookie)
print(isinstance(cookie, Iterable))
for item in cookie:
print("Name=" + item.name, end='\t\t')
print("Value=" + item.value)
4.2.3 保存cookie信息到文件中:
1). 指定年cookie文件存在的位置;
cookieFilenName = 'doc/cookie.txt'
2). 声明对象MozillaCookieJar, 用来保存cookie到文件中;
cookie = cookiejar.MozillaCookieJar(filename=cookieFilenName)
3). 通过urllib.request的 HTTPCookieProcessor创建cookie请求器;
handler = HTTPCookieProcessor(cookie)
4). 通过处理器创建opener; ==== urlopen
opener = request.build_opener(handler)
response = opener.open('http://www.baidu.com')
print(response.read().decode('utf-8'))
保存到本地文件中;
cookie.save(cookieFilenName)
4.2.4 从文件中获取cookie信息并访问:
1). 从文件中加载cookie信息
cookie.load(cookieFilenName)
2). 通过urllib.request的 HTTPCookieProcessor创建cookie请求器;
handler = HTTPCookieProcessor(cookie)
3). 通过处理器创建opener; ==== urlopen
opener = request.build_opener(handler)
response = opener.open('http://www.baidu.com')
print(response.read().decode('utf-8'))
4.3 模拟登陆并保存cookie信息:
cookieFileName = 'cookie.txt'
cookie = cookiejar.MozillaCookieJar(filename=cookieFileName)
handler = HTTPCookieProcessor(cookie)
opener = request.build_opener(handler)
# 这里的url是教务网站登陆的url;
loginUrl = 'xxxxxxxxxxxxxx'
postData = urlencode({
'stuid': '1302100122',
'pwd': 'xxxxxx'
})
response = opener.open(loginUrl, data=postData)
cookie.save(cookieFileName)