`

Python:网络爬虫相当利器

阅读更多

网络爬虫,又称为网页蜘蛛(WebSpider),非常形象的一个名字。如果你把整个互联网想象成类似于蜘蛛网一样的构造,那么我们这只爬虫,就是要在上边爬来爬去,顺便获得我们需要的资源。我们之所以能够通过百度或谷歌这样的搜索引擎检索到你的网页,靠的就是他们大量的爬虫每天在互联网上爬来爬去,对网页中的每个关键词进行索引,建立索引数据库。在经过复杂的算法进行排序后,这些结果将按照与搜索关键词的相关度高低,依次 

最近,主要的任务就是开发性感美女图片大全,使用python进行图片采集

1 urllib模块

urllib模块实际上是综合了url和lib的一个包。

url的一般格式为:

protocol://hostname[:port]/path/[;parameters][?query]#fragment

URL 由三部分组成:

第一部分是协议:http,https,ftp,file,ed2k…

第二部分是存放资源的服务器的域名系统或IP地址(有时候要包含端口号,各种传输协议都有默认的端口,如http的默认端口是80)

第三部分是资源的具体地址,如目录或者文件名等

举一个例子说明:

复制代码
import urllib.request
response = urllib.request.urlopen("http://www.meimei169.com/")
html = response.read()
print(html) #二进制数据

html = html.decode('utf-8') #对二进制数据解码
print(html)
复制代码

当遇到不了解的模块时,可通过IDLE中Help中打开Python的文档进行搜索查看,也可以使用print(模块名.__doc__)或者help(模块名)进行属性和使用方法的查看。如下为文档中urlopen的用法:

实例1:在placekitten网站下载一只猫的图片

复制代码
import urllib.request
response = urllib.request.urlopen("http://www.meimei169.com/") #urlopen返回一个对象
cat_img = response.read()  #对象均可用print()打印出来  # response.geturl() 得到url  #response.getcode() 返回值200,说明网站正常响应  response.info()得到文件信息
with open('cat_300_300.jpg','wb') as f:
    f.write(cat_img)
复制代码

可看到在当前运行目录下已成功下载了图片。

urlopen的url参数既可以是字符串也可以是一个request对象,则我们还可以将代码写成如下形式:

复制代码
import urllib.request
req = urllib.request.Request("http://www.meimei169.com/")
response = urllib.request.urlopen(req)

cat_img = response.read()
with open('cat_500_600.jpg','wb') as f:
    f.write(cat_img)
复制代码

实例2:利用百度翻译进行翻译

小甲鱼的视频中的实例是有道翻译,运行结果如下:

看弹幕说是有道翻译加了反爬虫机制,所以自己用百度翻译做了一个,研究了好一会儿,新手还是懵懵懂懂的,不过做出来了还是很开心的。代码如下所示:

复制代码
import urllib.request
import urllib.parse
import json

while True:
    content = input("请输入需要翻译的内容(退出q):")

    if content in['q','Q']:
        break
    else:

        url='http://www.meimei169.com/'

        data={}
        data['from'] = 'en'
        data['to'] = 'zh'
        data['query'] = content
        data['transtype'] = 'translang'
        data['simple_means_flag'] = 3

        data = urllib.parse.urlencode(data).encode('utf-8')


        response = urllib.request.urlopen(url,data)
        html = response.read().decode('utf-8')
        target = json.loads(html)
        print("翻译结果为:%s"%(target['trans_result']['data'][0]['dst']))
复制代码

打开翻译首页,点击翻译,在Network中找打方法为post的项,各个浏览器可能有差异,可尝试在Network里的XHR中查找。

代码中的url和data是复值表头中的url和Form Data,在IE浏览器中我找了好久,下面分别为360浏览器和IE浏览器的截图:

360:

IE:

接着我们解释此行代码:

data = urllib.parse.urlencode(data).encode('utf-8')

当data未赋值时,是以GET的方式提交,当data赋值后,POST将会取代GET将数据提交。如上图所示,data必须基于某一模式,我们使用urllib.parse.urlencode()即可将字符串转换为需要的模式。

代码中使用了josen模块,因为直接打印出html出来的是json格式的数据不利于直接观看。最终运行结果如下所示:

2 隐藏

为什么要进行隐藏操作?因为如果一个IP在一定时间访问过于频繁,那么就会被被访问网站进行反爬虫拦截,无法进行我们爬虫的后续工作了,所以要给爬虫披上一层神秘的面纱,从而瞒天过海喽~

两种方法隐藏(修改)headers:

(1)通过Request的headers参数修改

(2)通过Request.add_header(key,val)方法修改

文档中说到headers必须是字典的形式,所以方法(1)直接通过增加字典键和对应值的方式来进行隐藏,如下所示,找到Request Headers中的User-Agent对应的值进行添加。

复制代码
import urllib.request
import urllib.parse
import json

while True:
    content = input("请输入需要翻译的内容(退出q):")

    if content in['q','Q']:
        break
    else:

        url='http://www.meimei169.com/'

        head = {}
        head['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'

        data={}
        data['from'] = 'en'
        data['to'] = 'zh'
        data['query'] = content
        data['transtype'] = 'translang'
        data['simple_means_flag'] = 3

        data = urllib.parse.urlencode(data).encode('utf-8')

        req = urllib.request.Request(url,data,head)
        response = urllib.request.urlopen(req)
        html = response.read().decode('utf-8')
        
        target = json.loads(html)
        print("翻译结果为:%s"%(target['trans_result']['data'][0]['dst']))
复制代码

运行结果及headers是否正确输入的检查:

请输入需要翻译的内容(退出q):love
翻译结果为:爱
请输入需要翻译的内容(退出q):q
>>> req.headers #检查
{'User-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}

第二种方法:

复制代码
import urllib.request
import urllib.parse
import json

while True:
    content = input("请输入需要翻译的内容(退出q):")

    if content in['q','Q']:
        break
    else:

        url='http://www.meimei169.com/'

##        head = {}
##        head['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'

        data={}
        data['from'] = 'en'
        data['to'] = 'zh'
        data['query'] = content
        data['transtype'] = 'translang'
        data['simple_means_flag'] = 3

        data = urllib.parse.urlencode(data).encode('utf-8')

##        req = urllib.request.Request(url,data,head)#替换成下一句,因为不再引用上面的head所以去掉head
        req = urllib.request.Request(url,data)
        #使用add_header(key,value)
        req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36')

        response = urllib.request.urlopen(req)
        html = response.read().decode('utf-8')
        
        target = json.loads(html)
        print("翻译结果为:%s"%(target['trans_result']['data'][0]['dst']))
复制代码

第三种方法是引入休息时间,调用time模块的time.sleep来延长时间以避免网站认为是爬虫非法访问。

第四种方法是引入代理,代理把看到的内容返回给你,所以可以达到同样的效果。使用代理的步骤如下:

1. 参数是一个字典 {‘类型’:‘代理ip:端口号’}

proxy_support = urllib.request.ProxyHandler({})

2. 定制、创建一个 opener

opener = urllib.request.build_opener(proxy_support)

3a. 安装 opener
urllib.request.install_opener(opener)

3b. 调用 opener

opener.open(url)

复制代码
import urllib.request

url='http://www.meimei169.com/'
##iplist=['']

proxy_support = urllib.request.ProxyHandler({'http':'115.46.123.180:8123'})
#proxy_support = urllib.request.ProxyHandler({'http':random.choice(iplist)})

opener=urllib.request.build_opener(proxy_support)
opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36')]
urllib.request.install_opener(opener)

response=urllib.request.urlopen(url)
html=response.read().decode('utf-8')

print(html)
复制代码

运行结果如下所示,返回的IP地址是你的代理IP地址。

3 爬虫抓取煎蛋妹子图

跟着小甲鱼的视频去煎蛋网抓取妹子图啦,下述内容将自动进行和谐咔咔咔...

思路:新建本地保存图片文件夹→打开网站→记住图片的地址→保存图片到相应的文件夹

如图为煎蛋网妹子图网页显示,图片是按照页码来放置的。

我们发现点击不同的页码,url改变的只是页码处的数字。

http://jandan.net/ooxx/page-190#comments

首先我们要获取页码,在页码处右键点击审查元素,如下所示:

则我们可以读取到网页的html,然后使用find函数来找到[190]中的数字190,也就是当前页码。

接着我们要获取当前页码下每张图片的url,同样在图片点击右键选择审查元素,可看到图片的地址如下:

嘻嘻,是gakki。以上是准备工作,接着我们就可以写出大概的框架来,其余的内容由函数封装实现

复制代码
def download_mm(folder = 'ooxx',pages = 10):
    os.mkdir(folder)
    os.chdir(folder)
    
    url='http://www.meimei169.com/'
    page_num = int(get_page(url))

    for i in range(pages):
        page_num -= i
        page_url = url + 'page-' + str(page_num) + '#comments'
        img_addrs = find_imgs(page_url)
        save_imgs(folder,img_addrs)
复制代码

完整实现代码如下所示:

复制代码
import urllib.request
import os

def url_open(url):
    req = urllib.request.Request(url)
    req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36')

    response = urllib.request.urlopen(req)
    html = response.read()

    return html

def get_page(url):
    html = url_open(url).decode('utf-8')

    a = html.find('current-comment-page') + 23
    b = html.find(']',a)
    
    return html[a:b]
    
def find_imgs(url):
    html = url_open(url).decode('utf-8')
    img_addrs = []

    a = html.find('img src=')
    while a != -1:
        b = html.find('.jpg',a,a+255)
        if b != -1:
            img_addrs.append(html[a+9:b+4])
        else:
            b = a + 9
        a = html.find('img src=',b)

    return img_addrs

def save_imgs(folder,img_addrs):
    for each in img_addrs:
        filename = each.split('/')[-1]
        with open(filename, 'wb') as f:
            img = url_open("http:"+each)
            f.write(img)
    
def download_mm(folder = 'ooxx',pages = 10):
    os.mkdir(folder)
    os.chdir(folder)
    
    url='http://www.meimei169.com/'
    page_num = int(get_page(url))

    for i in range(pages):
        page_num -= i
        page_url = url + 'page-' + str(page_num) + '#comments'
        img_addrs = find_imgs(page_url)
        save_imgs(folder,img_addrs)

if __name__ =='__main__':
    download_mm()
复制代码

成功在本地新建的文件夹中获取到了jpg的图片。

4 异常处理

(1)URLError

当urlopen无法处理一个响应的时候,就会引发URLError异常。 通常,没有网络连接或者对方服务器压根儿不存在的情况下,就会引发这个异常。同时,这个URLError会伴随一个reason属性,用于包含一个由错误编码和错误信息组成的元组。

(2)HTTPError

HTTPError是URLError的子类,服务器上每一个HTTP的响应都包含一个数字的“状态码”。有时候状态码会指出服务器无法完成的请求类型,一般情况下Python会帮你处理一部分这类响应(例如,响应的是一个“重定向”,要求客户端从别的地址来获取文档,那么urllib会自动为你处理这个响应。);但是呢,有一些无法处理的,就会抛出HTTPError异常。这些异常包括典型的:404(页面无法找到),403(请求禁止)和401(验证请求)。

下述举例说明Python处理异常的两种方法:

复制代码
from urllib.request import Request,urlopen
from urllib.error import URLError,HTTPError
req = Request(someurl)
try:
    response = urlopen(req)
except HTTPError as e:
    print('The server coudln\'t fulfill the request.')
    print('Error code:',e.code)
except URLError as e:
    print('We failed to reach a server.')
    print('Reason:',e.reason)
else:
    #do something
复制代码

 

注意HTTPError要在URLError前面。

复制代码
from urllib.request import Request,urlopen
from urllib.error import URLError,HTTPError
req = Request(someurl)
try:
    response = urlopen(req)
except HTTPError as e:
    if hasattr(e,'reason')
        print('We failed to reach a server.')
        print('Reason:',e.reason)
    elif hasattr(e,'code'):
        print('The server coudln\'t fulfill the request.')
        print('Error code:',e.code)
else:
    #do something
复制代码

 

分享到:
评论

相关推荐

    基于Python的网络爬虫的毕业设计实现

    【Python网络爬虫毕业设计实现】是针对计算机科学与技术专业学生的一项常见课题,它旨在让学生掌握网络数据抓取的基本技能,并能应用到实际项目中。在这个设计中,Python作为主要的开发语言,因其简洁易读的语法和...

    利用Python实现网络爬虫 Hands-On-Web-Scraping-with-Python-master.zip

    《Python实战:网络爬虫详解》 Python是一种广泛应用于数据科学、机器学习和网络爬虫领域的强大编程语言。网络爬虫是获取大量网络数据的重要工具,尤其在机器学习项目中,高质量的数据集往往是成功的关键。本教程将...

    一小时入门python3网络爬虫

    一小时入门python3网络爬虫,入门教程,实战利器。。。

    Python3网络爬虫数据采集pdf.7z

    **Python3网络爬虫数据采集** 在信息技术领域,网络爬虫是一种自动提取网页信息的程序,它能够遍历互联网上的页面,抓取所需的数据。Python3作为一门强大的编程语言,因其简洁的语法和丰富的库支持,成为了网络爬虫...

    用Python写网络爬虫.pdf

    《用Python写网络爬虫》是一本专注于介绍如何利用Python编程语言进行网络数据抓取的书籍。Python因其简洁明了的语法和丰富的第三方库,在网络爬虫领域有着广泛的应用。这本书详细阐述了从基础到进阶的爬虫技术,旨在...

    Python网络爬虫源代码

    11. **Scrapy框架**:Scrapy是一个高级的Python爬虫框架,集成了爬取、解析、存储等功能,提供中间件接口进行自定义处理,适合大型项目的爬虫开发。 12. **实战项目**:理论学习后,实践是最好的老师。可以尝试爬取...

    书籍[用Python写网络爬虫]对应的配套全套源代码 共9个章节.rar

    《用Python写网络爬虫》是一本专注于Python网络爬虫技术的书籍,旨在帮助读者深入理解和实践Python在数据抓取领域的应用。这本书共分为九个章节,每个章节都包含了相应的源代码,使得学习过程更加直观和实践导向。...

    用Python写网络爬虫-35

    爬虫还可以用于科学研究,例如在线人类行为、在线社群演化、人类动力学研究、计量社会学、复杂网络、数据挖掘等领域的实证研究都需要大量数据,网络爬虫是收集相关数据的利器。 那么,用什么语言写爬虫?C、C++是一...

    python写网络爬虫

    `Scrapy`是一个强大的Python爬虫框架,它包含了请求调度、中间件处理、爬取策略等功能,适用于大型项目的爬虫开发。对于简单的爬虫,我们也可以自定义循环结构实现遍历和递归。 五、反反爬策略 网站通常会设置反爬...

    python网络爬虫教学ppt

    **Python网络爬虫教学PPT概述** Python网络爬虫是一种技术,用于自动化地从互联网上抓取大量数据。...这份PPT将是你入门和进阶的宝贵资源,通过深入学习和实践,你将成为一名熟练的Python爬虫开发者。

    课程大作业:Python爬虫.zip

    本课程大作业以"Python爬虫"为主题,旨在帮助学习者深入理解和实践Python爬虫的相关知识。通过这份资源,你可以系统地掌握Python爬虫的基础到进阶技巧。 首先,你需要了解Python的基础语法,包括变量、数据类型、...

    用Python写网络爬虫-35页

    3. 科学研究:在线人类行为、在线社群演化、人类动力学研究、计量社会学、复杂网络、数据挖掘等领域的实证研究都需要大量数据,网络爬虫是收集相关数据的利器。 选择合适的语言来写爬虫是非常重要的。常用的语言有C...

    Python爬虫利器二之Beautiful Soup的用法.zip_python_爬虫_爬虫 python_爬虫 pyth

    总的来说,Beautiful Soup作为Python爬虫开发的重要工具,以其简洁的API和强大的解析能力,极大地简化了数据提取的过程。通过熟练掌握Beautiful Soup的使用,你将能更好地应对各种复杂的网页结构,高效地实现你的...

    基于Python的网络爬虫的设计与实现.doc

    【Python网络爬虫设计与实现】 网络爬虫是自动化抓取互联网信息的程序,它能够按照预设的规则从特定的网站中获取所需的数据。在Python中,设计和实现网络爬虫具有诸多优势,因为Python提供了丰富的库和简洁的语法,...

    Python爬虫,轻松获取网络数据的利器!

    python爬虫在当今信息爆炸的时代,如何从海量的网络数据中获取有价值的信息,成为了一个重要的课题。Python爬虫作为一种自动获取网络数据的方法,可以帮助我们快速、高效地从网络上获取所需的信息。 Python爬虫是一...

    python网络爬虫基础教学.rar

    本教程涵盖了Python爬虫的基础教学,旨在帮助初学者快速掌握爬虫的基本技能。以下是根据提供的压缩包文件名,整理出的一些核心知识点: 1. **Requests库**: Requests库是Python中最常用的HTTP库,它允许我们向...

    python百度百科爬虫.zip

    Python是一种高级编程语言,以其简洁明了的语法和强大的功能深受程序员喜爱,尤其在数据处理、网络爬虫和Web开发领域。在这个“python百度百科爬虫.zip”压缩包中,包含了一个利用Python编写的程序,目标是抓取百度...

    python爬虫实战

    Python爬虫实战是初学者踏入网络数据抓取领域的绝佳起点。这一主题涵盖了Python语言的基础,网络请求,HTML解析,以及如何处理反爬策略等关键知识点。以下是对这些内容的详细阐述: 1. **Python基础**:Python是...

Global site tag (gtag.js) - Google Analytics