暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Python爬虫笔记(一)础知识简单整理

不会学习的邓小阳 2020-10-26
299

登陆时候的用户名和密码可以放在http的头部也可以放在http的body部分。


HTTPS是否可以抓取

由于https运用的加密策略是公开的,所以即使网站使用https加密仍然可以获得数据,但是类似于微信这样的app,它自己实现了一套加密算法,想要抓取数据就变得比较困难。

 

制作爬虫时需要注意的HTTP字段

HTTP请求头部分字段解释:

accept:表明请求的资源类型

accept-charset:表示请求的资源的编码方式

accept-encoding:表明发送方可以支持的编码方式,需要注意gzip,它表示的是压缩,服务器为了节省空间可能就会压缩资源,如果我们的http头部含有gzip,在爬虫中要记得用gzip解码。

connection:keep-alive:避免建立的TCP连接被关闭,当加载完所需要的全部资源后,会发送一个头部带有connection:close的http报文关闭TCP连接,因为爬虫不需要多次请求数据(例如加载网页时,获得了html文件后,还会请求获得css、js等文件),所以可以直接去掉,或者将值设置为close

cookie:一般的登陆策略是把登陆的信息写入cookie,服务器把cookie返回给客户端,客户端每次请求数据都会带上cookie,cookie中存储的数据一般比较小

 

 

HTTP响应头部分字段解释:

set—cookie:设置cookie

status:状态码,表明服务器响应请求的状态,状态码返回403,可能是需要登陆,或者是IP被封禁(如果是拨号上网(通过DHCP动态分配IP),一般等待十秒左右再次拨号即可分到不同的公网IP),状态码表示重定向时,在urllib2会自动对重定向做处理,如果状态码为5xx,不一定就是服务器宕机,在分布式爬虫中,如果爬取同一服务器的不同网页的多个爬虫连续收到5XX,则可能是服务器宕机

 

爬取网页的HTTP方法

网页的静态部分直接采用get方法即可获得

网页动态部分的ajax请求可能采用的get方法也可能采用post方法,可以使用web容器自动处理ajax

 

爬虫爬取网页的策略

爬虫爬取页面时,可以采用深度优先搜索(采用栈)或是广度优先搜索(采用队列)的策略(请查看图的遍历方式),不断爬取外链接,要注意外链接是否被访问过,可以采用BoomFilter

 

记录抓取过的网页的策略

1、将其抓取过的URL保存到数据库中,将url设置为不允许重复的主键,每次都查询数据库中是否存在该URL来防止URL重复,由于数据库是对磁盘进行操作,因此效率低下

2、将爬取过的url保存在哈希表中,哈希表位于内存中,且哈希表的查询速度快,从而提高效率,由于一个URL可能比较长,为了节省内存,可以采用MD5(将任意长度的数据量转换为一个固定长度的数字,通常是4个整型)等摘要算法,对URL进行压缩后存储。在百度谷歌上可以通过输入site:+域名来获得网站url的个数,根据网站的大小来进行哈希算法和存储数据结构的选择,从而初步确定存储url需要开辟的内存空间


简单练习——用python实现的BFS爬取豆瓣电影首页超链接

from urllib import request

from collections import deque

from pybloom_live import BloomFilter

from lxml import etree

import hashlib

 

class crawel_bfs:  

    request_header={

            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',

            'Accept-Encoding': 'br',

            'Accept-Language': 'zh-CN,zh;q=0.9',

            'Cache-Control': 'max-age=0',

            'Connection': 'keep-alive',

            'Cookie': 'bid=Kn9AT5duD7k; gr_user_id=32e433a7-19f0-4e17-80c4-56b58d7c0056; _vwo_uuid_v2=5985FEE132C29EC9C840D6C5EDD95323|67c2ccc8467fc02a9cce6928e86ea013; ll="118281"; __yadk_uid=I4Ki5RUaEWOUdpVIjJfRYo1MEuaW36hA; __utmv=30149280.16369; viewed="10483489_1115600_2230208_26857712_1569487_1623164_26708119_26677686"; __utma=30149280.965685249.1516632348.1528892392.1530880979.81; __utmc=30149280; __utmz=30149280.1530880979.81.57.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmt=1; __utmb=30149280.1.10.1530880979; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1530880982%2C%22https%3A%2F%2Fwww.douban.com%2F%22%5D; _pk_ses.100001.4cf6=*; __utma=223695111.2038558801.1520348154.1528892435.1530880982.55; __utmb=223695111.0.10.1530880982; __utmc=223695111; __utmz=223695111.1530880982.55.51.utmcsr=douban.com|utmccn=(referral)|utmcmd=referral|utmcct=/; _pk_id.100001.4cf6=da4243a2a9e242f1.1520348154.54.1530881042.1528892472.',

            'Host': 'movie.douban.com',

            'Referer': 'https://www.douban.com/',

            'Upgrade-Insecure-Requests': '1',

            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'

            }

    

    cur_level=0

    max_level=2

        

    download_bf=BloomFilter(1024*1024,0.01)

    

    childque=deque()

    nowque=deque()

    

    def __init__(self,url,file_md5name,file_urlname):

        self.file_urlNameMd5_name=file_md5name

        self.file_urlName_name=file_urlname

        self.deal_file_md5=open(self.file_urlNameMd5_name,'r')

        self.file_md5=self.deal_file_md5.readlines()

        #用于输入现有的文件

        for url_md5_name in self.file_md5:

            #-1表示的是换行符,读入时换行符不会占据两个字符

            self.download_bf.add(url_md5_name[:-1])

        self.deal_file_md5.close()

        self.file_md5=open(self.file_urlNameMd5_name,'a')     

        self.file_url=open(self.file_urlName_name,'a')

        self.nowque.append(url)

    

    def indeque(self,url):

        self.nowque.append(url)

        

    def outdeque(self):

        try:

            url=self.nowque.popleft()

            return url

        except Exception:

            self.cur_level+=1

            if self.cur_level==self.max_level:

                return None

            if len(self.childque)==0:

                return None

            self.nowque=self.childque

            self.childque=deque()

            return self.nowque.popleft()

        

    def crawler(self,url):

          try:

            #创建一个request对象,封装一个报文对象

            req=request.Request(url,headers=self.request_header)

            #发送报文

            response=request.urlopen(req)

            html_page=response.read()

            #按照固定编码解码

            html=etree.HTML(html_page.lower().decode('utf-8'))

            url_list=html.xpath('//a/@href')

            for url in url_list:

                if url.find('javascript:')!=-1:

                    continue

                if url.startswith('http://') is False:

                    if url.startswith('/') is True:

                        url='http://movie.douban.com'+url

                    else:

                        continue

                if url[-1]=='/':

                    url=url[:-1]

                temp=hashlib.md5(url.encode('utf-8')).hexdigest()

                if temp not in self.download_bf:

                    self.download_bf.add(url)

                    self.childque.append(url)

                    self.file_md5.write(temp+'\n')

                    self.file_url.write(url+'\n')

          except Exception:

            print("出现异常")

        

    def startcrawler(self):

        while True:

            url=self.outdeque()

            if url!=None:

                print("现在爬取"+url+"的超链接")

                self.crawler(url)

            else:

                break

        self.file_md5.close()

        self.file_url.close()

        

crawel=crawel_bfs("https://movie.douban.com/",'urlmd5.txt',

                  'urlname.txt')

crawel.startcrawler()


文章转载自不会学习的邓小阳,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论