Python3爬虫实战(urllib模块)

2018.01.27 。我的第一篇博客。

在自学Python的过程中,爬虫是我学的最有趣的一个方面,现在我把学习爬虫的总结展示出来。

Python爬虫中,第一个接触的模块就是urllib,下面我将通过实战教学告诉大家如何使用urllib中的request模块构造爬虫,使用工具为Pycharm。

1.Request

urllib.request.Request(url, data=None, headers={}, method=None)

使用Request() 来创建Request对象,并添加请求参数。headers参数为用字典形式设置请求头。

from urllib import request

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'}
req = request.Request(url,headers=header)
# 也可以使用add_header()方法添加请求头
# req = 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')


2.urlopen

urllib.request.urlopen(urldata=None[timeout]*cafile=Nonecapath=Nonecadefault=Falsecontext=None)

 url:  需要打开的网址

 timeout:设置网站的访问超时时间

使用1里的Request() 来包装请求后,用urllib.request模块的urlopen() 获取页面,使用read()方法获得的页面,数据格式为bytes类型,需要通过decode()解码,转换成str类型。

扫描二维码关注公众号,回复: 2295648 查看本文章
from urllib import request

'''
url = 'http://www.baidu.com'
response = request.urlopen(url)
response.read().decode('utf-8')
'''

# 通常网站都会检查请求参数,所以爬虫最好添加请求头参数
# req 是1中添加请求头后的Request对象
response = request.urlopen(req)
response.read().decode('utf-8')


下面我们来进行实战检验


一.爬取妹子图。(目标网址:http://www.meizitu.com/
import urllib.request
import os
import re
import time

def url_open(url):
    # 创建一个 Request对象 req
    req = urllib.request.Request(url)

    # 通过 add_header( )方法添加请求头,防止基本的网站反爬策略
    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")

    # 将获取的网页信息通过read()方法读取出来
    response = urllib.request.urlopen(req).read()
    return response

# 另一种方法获取网页
'''
def url_open(url):
    req = urllib.request.Request(url)
    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"
    )
    # 创建opner对象
    opener = urllib.request.build_opener()

    # 给该对象添加请求头
    opener.addheaders = [header]

    # 用open方法获取网页并读取
    response = opener.open(url).read()
    return response
'''

def find_imgs(url):
    # 将网页内容进行解码,网页编码是GBK,就换成gbk
    html = url_open(url).decode('utf-8')

    # 使用正则表达式获取目标数据
    p = r'<img src="([^"]+\.jpg)"'
    img_addrs = re.findall(p, html)

    return img_addrs

def download_mm(folder='OOXX'):
    os.mkdir(folder)
    os.chdir(folder)

    page_num = 1  # 设置为从第一页开始爬取,可以自己改
    x = 0  # 自命名图片
    img_addrs = []  # 防止图片重复

    # 只爬取前两页的图片,可改,同时给图片重命名
    while page_num <= 2:
        page_url = url + 'a/more_' + str(page_num) + '.html'
        addrs = find_imgs(page_url)
        print(len(addrs))
        # img_addrs = []
        for i in addrs:
            if i in img_addrs:
                continue
            else:
                img_addrs.append(i)
        print(len(img_addrs))
        for each in img_addrs:
            print(each)
        page_num += 1
        time.sleep()
        # x = (len(2img_addrs)+1)*(page_num-1)
    for each in img_addrs:
        filename = str(x) + '.' + each.split('.')[-1]
        x += 1
        with open(filename, 'wb') as f:
            img = url_open(each)
            f.write(img)
        # page_num += 1

if __name__ == '__main__':
    url = 'http://www.meizitu.com/'
    download_mm()


二.爬取百度贴吧图片 (目标网址:https://tieba.baidu.com/p/5085123197)
# -*-coding:utf-8 -*-

import urllib.request
import re
import os

def open_url(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/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0")
    response = urllib.request.urlopen(req).read()

    return response

def find_img(url):
    html = open_url(url).decode('utf-8')
    p = r'<img class="BDE_Image" src="([^"]+\.jpg)"'
    img_addrs = re.findall(p, html)

    for each in img_addrs:
        print(each)
    for each in img_addrs:
        file = each.split("/")[-1]
        with open(file, "wb") as f:
            img = open_url(each)
            f.write(img)

def get_img():
    os.mkdir("TieBaTu")
    os.chdir("TieBaTu")
    find_img(url)

if __name__ == "__main__":
    url = 'https://tieba.baidu.com/p/5085123197'
    get_img()


3.urllib.parese.urlencode(

urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors=None)

urlencode()主要作用就是将url附上要提交的数据。 

通过下面这个爬取有道词典的例子大家就会清楚urllib.parse.urlencode()的用处了。

import urllib.request
import  urllib.parse
import json

while True:
    content = input("请输入:")
    if content == "":
        print("欢迎下次使用")
        break
    data = {
         'i': content
        , 'from': 'AUTO'
        , 'to': 'AUTO'
        , 'smartresult': 'dict'
        , 'client': 'fanyideskweb'
        , 'salt': '1514345577426'
        , 'sign': '8a12c3bae1619e0d60247aa90a4d945e'
        , 'doctype': 'json'
        , 'version': '2.1'
        , 'keyfrom': 'fanyi.web'
        , 'action': 'FY_BY_REALTIME'
        , 'typoResult': 'false'
        }
    data = urllib.parse.urlencode(data).encode('utf-8')
    url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&sessionFrom=null'
    req = urllib.request.Request(url,data)
    req.add_header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0")
    response = urllib.request.urlopen(req)
    html = response.read().decode('utf-8')
    
    # 因为翻译后的数据是通过json格式返回的,所以要添加json模块进行解析
    target = json.loads(html)
    # print(html)
    print("翻译结果:")
    print(target['translateResult'][0][0]['tgt'])
    print()


通过上述三个例子,我想大家应该知晓如何进行自己目标网页的爬取了。
总结:
1.熟练使用urllib模块的方法,清楚这些方法分别实现了什么功能以及在什么地方使用这些方法;
2.学会使用正则表达式匹配网页源码中的目标数据;
3.知道os等模块的功能以及作用。

猜你喜欢

转载自blog.csdn.net/mr_blued/article/details/79180017