第一章:网络爬虫之前奏

网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

网络爬虫按照系统结构和实现技术,大致可以分为以下几种类型:通用网络爬虫(General Purpose Web Crawler)、聚焦网络爬虫(Focused Web Crawler)、增量式网络爬虫(Incremental Web Crawler)、深层网络爬虫(Deep Web Crawler)。 实际的网络爬虫系统通常是几种爬虫技术相结合实现的。

第一单元:request

Response对象

#requests.get(url,params=None,**kwargs),使用标准式
import requests
r=requests.get('https://www.baidu.com')
#r为Response对象,包含了从url获取的全部信息
r.status_code             #200表示访问成功
r.text                    #响应内容的字符串形式,既url对应页面的内容
r.encoding                #从HTTPheader中猜测的相应内容编码方式
r.apparent_encoding       #从内容中分析出相应内容编码方式
r.content                 #HTTP响应内容的二进制形式
r.headers                 #反馈头部信息内容

实例1

import requests
r=requests.get('https://www.baidu.com')
print(r.encoding)
print(r.text)
print(r.apparent_encoding)
r.encoding='utf-8'
print(r.text)

异常处理

requests.ConnectionError    #网络连接误异吊,ODNS查询矢败、拒绝连投等
requests.HTTPError          #HTTP错误异常
requests.URLRequired        #URL缺失异常
requests.TooManyRedirects   #超过最大重定向次数,产生重定向异常
requests.ConnectTimeout     #连接远程服务器超时异常
requests.Timeout            #请求URL超时,产生超时异常

实例2:爬取网页的通用代码框架

import requests

def getHTMLText(url):
    try:
        r=requests.get(url,timeout=30)
        r.raise_for_status()
#所有网络连接错误时的异常,如果不是200,产生异常requests.HTTPError
        r.encoding=r.apparent_encoding
        return r.text
    except:
        return '产生异常'
if __name__=='__main__':
    url='http://.baidu.com'
    print(getHTMLText(url))

HTTP协议 超文本传输协议

第一次请求与第二次无关联,请求与响应

URL实例http://.baidu.com,类似电脑中的文件路径

Requests库的七个主要方法

requests.request()  #构造一个请求,支撑以下各方法的基础方法
requests.get()      #获取HTML网页的主要方法,对应于HTTP的GET
requests.head()     #获取HTML网页头信息的方法,对应于HTTP的HEAD
requests.post()     #向HTML网页提交POST请求的方法,追加,对应于HTTP的POST
requests.put()      #向HTML网页提交PUT请求的方法,覆盖,对应于HTTP的PUT
requests.patch()    #向HTML网页提交局部修改请求,对应于HTTP的PATCH
requests.delete()   #向HTML页面提交删除请求,对应于HTTP的DELETE

requests.get(method,url,**kwargs),使用标准式

method:请求方式,有GET,HEAD,POST,PUT,PATCH,OPTIONS,delete等六种

  • *kwargs:13个控制访问参数

requests.get(url,params=None,**kwargs),使用标准式

params:字典或字节序列,作为参数增加到url中
data:字典,字节序列或文件对象,作为Request的内容
json:JSON格式的数据,作为Request的内容
headers:字典,HTTP定制头(模拟浏览器进行访问)
cokies:字典或CpplieJar,Request中的cookie
auth:元祖,支持HTTP认证功能
files:字典类型,传输文件
timeout:设定超时时间,秒为单位
proxies:字典类型,设定访问代理服务器,可以增加登陆认证
allow_redirects:True//False,默认为True,重定向开关
stream:True/False,默认为True,获取内容立即下载开关
verify:True/False,默认为True,认证SSL证书开关
cert:本地SSL证书路径"""
hd = {'user-agent':'Chrome/10'}
r = requests.request('POST','http://python123.io/ws',headers=hd)

第二单元:盗亦有道

网络爬虫的规模

小规模:Requests 中规模:Scrapy 大规模:定制开发

Robots协议

类似网站发布公告,告知什么可以爬取,什么不能爬取

#注释,*代表所有,/代表根目录
User-agent:*   #不允许所有爬虫去爬取禁爬的内容
Disallow:/     #对于某个User-agent,所有资源都不能爬

第三单元:网络爬取实例

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

import requests
url="https://item.jd.com/2967929.html"
try:
    kv = {'user-agent': 'Mozilla/5.0'}
    r=requests.get(url,headers = kv)
    print(r.status_code)
    r.raise_for_status()
    r.encoding=r.apparent_encoding
    print(r.text[:1000])
except:
    print('爬取失败')

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

import requests
url="https://www.amazon.cn/dp/B07T97N559/?_encoding=UTF8&pd_rd_w=vBxaZ&pf_rd_p=ab8ff3db-69bf-4689-812a-0e8bc890ffc2&pf_rd_r=8R53G9JVZWF3TAC7QWG3&pd_rd_r=54faa6ab-f398-47dc-9bb0-3519f0a663cd&pd_rd_wg=30sZz&ref_=pd_gw_unk"
try:
    kv = {'user-agent': 'Mozilla/5.0'}
    r=requests.get(url,headers = kv)
    print(r.status_code)
    print(r.request.headers)     #获取r中request的头
    r.raise_for_status()
    r.encoding=r.apparent_encoding
    print(r.text[1000:2000])
except:
    print('爬取失败')

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

#百度
import requests
url='https://www.baidu.com/s'
try:
    kv = {'wd':'keyword'}
    r=requests.get(url,params = kv)
    print(r.request.url)
    r.raise_for_status()
    print(len(r.text))
except:
    print('爬取失败')
#360
import requests
url='https://www.so.com/s'
try:
    kv = {'q':'keyword'}
    r=requests.get(url,params = kv)
    print(r.request.url)
    r.raise_for_status()
    print(len(r.text))
except:
    print('爬取失败')

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

import requests
import os

#自定义名存取
url='https://c-ssl.duitang.com/uploads/item/201804/28/20180428114907_txvnc.thumb.1000_0.jpg'
root='E:/b.jpg'
try:
    if not os.path.exists(root):
        r=requests.get(url)
        with open(root,'wb') as f:          #以二进制写入的方式打开
            f.write(r.content)              #将返回内容的二进制写入文件
            print('文件保存成功')
    else:
        print('文件已存在')
except:
    print('爬取失败')

#创建目录以原名存取
url='https://c-ssl.duitang.com/uploads/item/201804/28/20180428114907_txvnc.thumb.1000_0.jpg'
root='E:/test0/'
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)
            print('文件保存成功')
    else:
        print('文件已存在')
except:
    print('爬取失败')

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

import requests
url = 'https://m.ip138.com/iplookup.asp?ip='
try:
    kv = {'user-agent': 'Mozilla/5.0'}
    r=requests.get(url+'222.190.7.25',headers = kv)
    print(r.status_code)
    r.raise_for_status()
    r.encoding=r.apparent_encoding
    print(r.text[-5000:])
except:
    print("爬取失败")