爬虫从头学之Requests+BeautifulSoup爬取妹子图

  1. 爬取思路

    目标网站妹子图url:http://www.meizitu.com/a/more_1.html

    通过观察我们发现,索引页包含图片所在网页的连接,我们可以通过索引页的连接地址访问详情页,进而找到图片。所以思路就是1. 索引页—2. 分析索引页得到详情页的地址— 3. 访问详情页—- 4. 分析详情页得到图片的地址,— 5. 进而下载到本地

    爬取结果:
    这里写图片描述

  2. 实战部分

    需要用到的技术

    requests库的基本用法

    BeautifulSoup库的基本用法

import os 
import requests
from requests import RequestException
from bs4 import BeautifulSoup
from hashlib import md5
from multiprocessing import Pool
  1. 访问索引页

    使用requests库访问索引页,查看网页源代码发现网页编码为 ‘gb2312’ ,需要修改返回编码

# 访问索引页
def get_page_index(url):
    try:
        response = requests.get(url)
        if response.status_code == 200:
            # 转换编码
            response.encoding = 'gb2312'
            #print(response.text)
            return response.text
        return None
    except RequestException:
        print('访问索引页出错',url)
  1. 得到详情页(图片所在页面)的地址

    浏览器中审查元素,发现详情页的地址在一个类名为’ . pic ’ 下的 a 标签中 ’ href ‘中,使用BeautifulSoup解析网页,选择解析器为 ’ lxml ’ 之后使用生成器返回地址

# 处理索引页
def parse_page_index(html):
    soup = BeautifulSoup(html, 'lxml')
    page_urls = soup.select(".pic > a")
    for item in page_urls:
        # print(item)
        yield item.attrs['href']
  1. 访问详情页
#访问详情页
def get_page_detail(url):
    print('正在访问',url)
    try:
        response = requests.get(url)
        if response.status_code == 200:
            response.encoding = 'gb2312'
            return response.text
        return None
    except RequestException:
        print('访问详情页出错',url)
        return None
  1. 分析详情页得到图片的地址

    分析详情页,图片在 id 为 ’ picture ‘下 p 标签下的 img 标签中,调用下载图片的函数,将图片地址下的图片下载下来。

# 解析详情页
def parse_page_detail(html):
    print('正在解析')
    soup = BeautifulSoup(html,'lxml')
    page_urls = soup.select('#picture > p > img')
    for page_url in page_urls:
        download_pic(page_url.attrs['src'])
  1. 下载图片到本地

    得到图片所在的地址后,我们可以发现,图片并不是保存在该网站上的而是托管在其他的网站,该网站需要设置请求头,否则会拒绝爬虫访问。之后设置图片保存的路径,使用MD5将图片的名字统一长度,避免重名。

#访问图片地址并下载
def download_pic(url):
    print('访问图片地址',url)
    header = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
    }
    try:
        response = requests.get(url,headers = header)
        if response.status_code == 200:
            content = response.content
            file_path = '{0}/{1}.{2}'.format(os.getcwd()+'/picture2',md5(content).hexdigest(),'jpg')
            if not os.path.exists(file_path):
                with open(file_path,'wb') as f:
                    f.write(content)
                    f.close()
                    #print('ok')
    except RequestException:
        print('访问图片或存储出错')

main函数

def main(index):
    html = get_page_index('http://www.meizitu.com/a/more_'+ str(index) +'.html')
    # parse_page_index使用yield生成器返回信息
    for detail_page_url in parse_page_index(html):
        detail_html = get_page_detail(detail_page_url)
        parse_page_detail(detail_html)
    print('爬取完成')
if __name__ == '__main__':
    # 多线程爬取第一页和第二页
    pool = Pool()
    groups = [i for i in range(1,3)]
    pool.map(main,groups)

源码地址:
https://github.com/Link-Secret/Python-crawler/blob/master/spider/meizitu.py

相关文章
相关标签/搜索