爬虫(初识爬虫)

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)

猜你喜欢

转载自blog.csdn.net/qq_43281189/article/details/87893530