您的位置:时时app平台注册网站 > 编程知识 > 爬取妹子图(requests BeautifulSoup)

爬取妹子图(requests BeautifulSoup)

2019-11-28 03:16

图片 1

3.分析网页源代码

通过审查网页元素定位到了总页数的html元素:<a href="/home/79" class="last">最旧</a> 由此可以得出该网址的总页数为79页,接下来便可对其进行提取

def get_page_name(url):#获得图集最大页数和名称
    html = get_html(url)
    soup = BeautifulSoup(html, 'lxml')
    span = soup.findAll('span')
    title = soup.find('h2', class_="main-title")
    return span[10].text, title.text

1.确定目标网址

图片 2

www.mmjpg.com

Hostreferer = {
    'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
    'Referer':'http://www.mzitu.com'
}
Picreferer = {
    'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
    'Referer':'http://i.meizitu.net'
}

12.大功告成,运行代码

图片 3

编辑器执行过程

图片 4

以图集名命名的文件夹

图片 5

对应图集里面的所有图片

本实验的完整代码在Github上,欢迎fork

 1 import requests
 2 from bs4 import BeautifulSoup
 3 import os
 4 import re
 5 
 6 Hostreferer = {
 7     'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
 8     'Referer':'http://www.mzitu.com'
 9 }
10 Picreferer = {
11     'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
12     'Referer':'http://i.meizitu.net'
13 }
14 
15 def get_page_name(url):#获得图集最大页数和名称
16     html = get_html(url)
17     soup = BeautifulSoup(html, 'lxml')
18     span = soup.findAll('span')
19     title = soup.find('h2', class_="main-title")
20     return span[10].text, title.text
21 
22 def get_html(url):#获得页面html代码
23     req = requests.get(url, headers=Hostreferer)
24     html = req.text
25     return html
26 
27 def get_img_url(url, name):
28     html = get_html(url)
29     soup = BeautifulSoup(html, 'lxml')
30     img_url = soup.find('img', alt= name)
31     return img_url['src']
32 
33 def save_img(img_url, count, name):
34     req = requests.get(img_url, headers=Picreferer)
35     new_name = rename(name)
36     with open(new_name '/' str(count) '.jpg', 'wb') as f:
37         f.write(req.content)
38 
39 def rename(name):
40     rstr = r'[/\:*?<>|]'
41     new_name = re.sub(rstr, "", name)
42     return new_name
43 
44 def save_one_atlas(old_url):
45     page, name = get_page_name(old_url)
46     new_name = rename(name)
47     os.mkdir(new_name)
48     
49     print("图集--"   name   "--开始保存")
50     for i in range(1, int(page) 1):
51         url = old_url   "/"   str(i)
52         img_url = get_img_url(url, name)
53         # print(img_url)
54         save_img(img_url, i, name)
55         print('正在保存第'   str(i)   '张图片')
56     print("图集--"   name   "保存成功")
57 
58 
59 def get_atlas_list(url):
60     req = requests.get(url, headers=Hostreferer)
61     soup = BeautifulSoup(req.text, 'lxml')
62     atlas = soup.find_all(attrs={'class':'lazy'})
63     atlas_list = []
64     for atla in atlas:
65         atlas_list.append(atla.parent['href'])
66     return atlas_list
67 
68 def save_one_page(start_url):
69     atlas_url = get_atlas_list(start_url)
70     for url in atlas_url:
71         save_one_atlas(url)
72 
73 
74 if __name__ == '__main__':
75     start_url = "http://www.mzitu.com/"
76     for count in range(1, 3):
77         url = start_url   "page/"   str(count)  "/"
78         save_one_page(url)
79     print("爬取完成")

10.创建文件夹并用图集名进行命名

def mk_pic_dir(self, dirname):
    path = dirname
    if not os.path.exists(path):
        os.mkdir(path)
    return path

 

4.引入所需要的库

import os
import re
import urllib2                                                                                                          
from lxml import html     

  目标网站:妹子图

5.获取网页源代码

def get_source_page(self, url):
    '''
    返回经过lxml.html.fromstring 模块处理的<Element html at 0x36e8278>
    可以用 XPath 来过滤数据
    '''
    try:
        response = urllib2.urlopen(url, timeout=3).read()
        selector = html.fromstring(response)
    except:
        selector = None
    finally:
        return selector

  得到图片url链接之后要讲图片存到本地,在请求图片url的时候要加入Picreferer,否则网站会认为你是一个爬虫,会返还给你一个盗链图

9.获取图片的src属性

def get_pic_link(self, url):
    try:
        selector = self.get_source_page(url)
        src = selector.xpath('//div[@id="content"]/a/img/@src')[0]
    except:
        src = None
    finally:
        return src

这里作为测试,所以只爬取前两页图集。改变range内的参数,即可改变爬取页数。

2.分析网页URL变化

通过打开不同页数的页面内容后发现
第二页:http://www.mmjpg.com/home/2
第三页:http://www.mmjpg.com/home/3
每当我们点击一个页面,url改变的是最后面的数字,因此我们需要找到总页数的html代码,才能对其进行爬虫翻页

将爬取一整夜图集进行封装,方便后续的翻页爬取

6.获取总页数

def get_sum_page(self, url):
    selector = self.get_source_page(url)
    '''使用xpath提取网页中总页数的元素'''
    sum_page = selector.xpath('//div[@class="page"]//a[last()]/@href')[0].split('/')[-1]
    return sum_page

下面准备开始多个页面的爬取,先将前面爬取一个图集的方法进行封装

11.进入所有图集,并下载所有图片

def download_all_pic(self, page_links):
    for page_link in page_links:
        try:
            selector = self.get_source_page(page_link)
            album_title = selector.xpath('//div[@class="article"]/h2/text()')[0]
            sum_pic = selector.xpath('//div[@id="page"]/a[last()-1]/text()')[0]
            path = self.mk_pic_dir(album_title)
        except:
            continue
        for pic in range(1, int(sum_pic)   1):
            try:
                print u'正在下载-->'   album_title   u'-->第'   str(pic)   u'张美图...'
                pic_link = page_link   '/'   str(pic)
                src = self.get_pic_link(pic_link)
                filename = '%s.jpg' % (pic)
            except:
                continue
            else:
                try:
                    '''增加打开图片链接时的头部referer属性'''
                    req = urllib2.Request(src)
                    req.add_header('Referer', 'http://img.mmjpg.com/')
                    '''写入文件'''
                    with open(path   '/'   filename, 'wb') as fp:
                        fp.write(urllib2.urlopen(src, timeout=3).read())
                 except:
                    continue

这里采用re库,将name中含有的非法字符换成空,可以看做直接去掉。

8.获取每个图集的链接

'''由于首页图片点击进去之后还有图片,因此首页图片是一个图集链接,所以得先获取图集链接,进而获取里面的所有图片,分析网页代码得知,可对其连接进行提取,并同样返回一个list'''
def get_page_links(self, urls):
    page_links = []
    for url in urls:
        try:
            selector = self.get_source_page(url)
            lis = selector.xpath('//div[@class="pic"]//li/a/@href')
        except:
            continue
        for li in lis:
            page_links.append(li)
    return page_links

 

7.用总页数来组合拼接出所有页面的url,并返回包含所有url的list

def get_all_page_urls(self, sumpage):
    urls = []
    baseurl = 'http://www.mmjpg.com/home/'
    ul = baseurl.split('/')
    for page in range(1, int(sumpage)   1):
        ul[-1] = str(page)
        url = '/'.join(ul)
        urls.append(url)
    return urls

我爬了3个多G的图片花了我接近4个小时,足以证明效率是真的低。

需求:最近对python爬虫感兴趣,于是学习了下python爬虫并找了个网站练习,练习网址:http://www.mmjpg.com,其中每一套图都是一张一个页面,存一套图如果是手动得点翻几十个页面,但如果使用爬虫的话,就很方便了,轻轻松松就可以把美女存到硬盘了。

所以需要将前面的代码进行修改,加入一个rename方法,将这些字符换成可行的字符。(在这里我就直接将这些字符去掉)

实验环境:

  • Windows 10,Python 2.7.6,Pycharm

图片 6

图片 7图片 8

爬取结果

这是我写的第一篇较长的博客,还有很多未完善的地方,希望大家见谅。

翻页爬取

爬取一整页图集

 

而最大页数只是被span标签包含,无法通过属性来提取。所以提取图集名称采取标签名 属性名一起提取,而最大页数就采取将span标签全部找出,最大页数在span标签中第11位,

 

这个程序能够爬取图片,但是效率太低,正在学习多进程,希望之后可以提高该程序的爬取效率。

  使用requests库和BeautifulSoup库

def save_img(img_url, count, name):
    req = requests.get(img_url, headers=Picreferer)
    with open(name '/' str(count) '.jpg', 'wb') as f:
        f.write(req.content)

完整代码

  文件夹名称即为图集名称,内部图片以页数作为文件名。

 

获得图片url链接

首先网站的分析,该网站有一定的反爬虫策略,所以应对就是加入headers(目前是小白,目前不知道具体为毛这样做)

 

爬取一个图集

 

爬取一个图集完整代码

前一个头作为请求网站,后一个头作为破解盗链使用

def save_one_page(start_url):
    atlas_url = get_atlas_list(start_url)
    for url in atlas_url:
        save_one_atlas(url)

 

并且在爬取过程中出现一个问题,提示 你的主机中的软件中止了一个已建立的连接 ,这个问题还未找到解决方法,也未找明产生的具体原因。

第一页是初始网址,但是页数为1的链接也是直接进入第一页,所以所有页的url就可以用以上通式改变页数进行遍历。

分析网页构成如图所示,图集名称包含在h2标签内,且该标签在整个HTML代码里有唯一的class="main-title",

获得页面HTML代码

import re
def rename(name):
    rstr = r'[/\:*?<>|]'
    new_name = re.sub(rstr, "", name)
    return new_name

def save_one_atlas(old_url):
    page, name = get_page_name(old_url)
    new_name = rename(name)
    os.mkdir(new_name)

    print("图集--"   name   "--开始保存")
    for i in range(1, int(page) 1):
        url = old_url   "/"   str(i)
        img_url = get_img_url(url, name)
        # print(img_url)
        save_img(img_url, i, name)
        print('正在保存第'   str(i)   '张图片')
    print("图集--"   name   "保存成功")

 

获得图集名称以及图集最大页数

今天是对于单个图集的爬取,就选择一个进行爬取,我选择的链接为:

def get_atlas_list(url):
    req = requests.get(url, headers=Hostreferer)
    soup = BeautifulSoup(req.text, 'lxml')
    atlas = soup.find_all(attrs={'class':'lazy'})
    atlas_list = []
    for atla in atlas:
        atlas_list.append(atla.parent['href'])
    return atlas_list

在进行爬取一个图集前先加入一个方法,在爬取图集名称的时候,由于名称的字符不限,所以可能出现含有文件夹中不能出现的一些字符,例如:/ : ? < > 等

该方法传入的参数有3个,第一个是图片url,第二个当前图片的页数,用作创建文件,第三个是图集名称,在存储之前先创建了一个名称是图集名称的文件夹,这样就能将图片存入指定文件夹

分析页面url,发现每一页均是初始网址 page/ 页数/

 

import requests
from bs4 import BeautifulSoup
import os

Hostreferer = {
    'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
    'Referer':'http://www.mzitu.com'
}
Picreferer = {
    'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
    'Referer':'http://i.meizitu.net'
}

def get_page_name(url):#获得图集最大页数和名称
    html = get_html(url)
    soup = BeautifulSoup(html, 'lxml')
    span = soup.findAll('span')
    title = soup.find('h2', class_="main-title")
    return span[10].text, title.text

def get_html(url):#获得页面html代码
    req = requests.get(url, headers=Hostreferer)
    html = req.text
    return html

def get_img_url(url, name):
    html = get_html(url)
    soup = BeautifulSoup(html, 'lxml')
    img_url = soup.find('img', alt= name)
    return img_url['src']

def save_img(img_url, count, name):
    req = requests.get(img_url, headers=Picreferer)
    with open(name '/' str(count) '.jpg', 'wb') as f:
        f.write(req.content)

def main():
    old_url = "http://www.mzitu.com/123114"
    page, name = get_page_name(old_url)
    os.mkdir(name)
    for i in range(1, int(page) 1):
        url = old_url   "/"   str(i)
        img_url = get_img_url(url, name)
        #print(img_url)
        save_img(img_url, i, name)
        print('保存第'   str(i)   '张图片成功')
main()
start_url = "http://www.mzitu.com/"
    for count in range(1, 3):
        url = start_url   "page/"   str(count)  "/"
        save_one_page(url)
def get_img_url(url, name):
    html = get_html(url)
    soup = BeautifulSoup(html, 'lxml')
    img_url = soup.find('img', alt= name)
    return img_url['src']

 

 

 

View Code

然后图片的每一页是     图集首页  / 当前页数,得到含有图片内容的url链接,后面就可以将得到图片存入本地。

 

将图片存入本地

用requests库的get方法,加上Hostreferer

  在main方法中先请求到图集的名称和最大页数,并且使用名称创建一个文件夹来存储图片。再从1到最大页数做一个for循环,

 

 

分析一个页面中的url链接,发现如果找 target="_blank" 这一属性,则会产生很多多余的链接,所以我直接从字标签入手找到属性 class="lazy"的img标签,然后再在寻找到img标签的父标签中的href

  分析页面内容,含有图片链接的img标签中有一个alt属性的值是跟图集名称相同,可以用这个来直接找到这个标签,当然也可以先找到div标签中的class属性是main-inage,再找到img的src属性,这里我就采用第一种方法。

  刚刚入门爬虫,今天先对于单个图集进行爬取,过几天再进行翻页爬取。

def get_html(url):#获得页面html代码
    req = requests.get(url, headers=Hostreferer)
    html = req.text
    return html

 

 图片 9

本文由时时app平台注册网站发布于编程知识,转载请注明出处:爬取妹子图(requests BeautifulSoup)

关键词: