【美高梅开户网址】自然是你的操作不够骚,分析Ajax来抓取天涯论坛街拍美图

  程序员为何一向不女对象呢?那些难点应有多三人都有麻烦,刚搜的360查究最热浏览就是是那几个,比秃头还看好,是应有研究一下了。小编认为根本有两点!

encoding=utf8

import requests
from requests.exceptions import RequestException
import urllib
import json
import re
from bs4 import BeautifulSoup
from config import *
def get_index(offset,keyword):
data={
‘offset’:offset,
‘format’:’json’,
‘keyword’:keyword,
‘autoload’:’true’,
‘count’:20,
‘cur_tab’:3
}
url=’http://www.toutiao.com/search\_content/?’+urllib.urlencode(data))
response=requests.get(url)
try:
if response.status_code == 200:
return response.text
return None
except RequestException:
print u’请求索引页出错’
return None
def parse_page_index(html):
#将json格式的字符串转化成python对象,对象转变来json用 json.dumps()
data=json.loads(html)
if data and ‘data’ in data.keys():
for item in data.get(‘data’):
#yield 是url生成器 即取出article_url并生成url
yield item.get(‘article_url’)
def get_page_detail(url):
response = requests.get(url)
try:
if response.status_code == 200:
return response.text
return None
except RequestException:
print ‘请求详细的情况页出错’
return None
def parse_page_detail(html,url):
soup=BeautifulSoup(html,’lxml’)
title = soup.select(‘title’)[0].get_text()
images_pattern= re.compile(‘var gallery = (.*?);’,re.S)
result = re.search(images_pattern,html)
if result:
data =json.loads(result.group(1))
sub_images = data.get(‘sub_images’)
images = [item.get(‘url’) for item in sub_images]
return {
‘title’ :title,
‘url’:url,
‘images’:images
}
def main():
html=get_index(0,’街拍’)
for url in parse_page_index(html):
html=get_page_detail(url)
if html:
result=parse_page_detail(html,url)
print result[‘title’]
if name == ‘main‘:
main()

正文是学习 天善大学 Python3爬虫三大案例实战分享 /
分析Ajax抓取乐乎街拍美图
【美高梅开户网址】自然是你的操作不够骚,分析Ajax来抓取天涯论坛街拍美图。 后所写,谢谢崔庆才崔先生。
  天善高校Python爬虫3大案例实战分享
抓取的是街拍中的图集标签下的原委

 美高梅开户网址 1

image.png

 

流程:
 1. 抓取索引页
 二. 抓取详细情况页内容
 三. 保存音讯到数据库
 ④. 下载图片

1、和管理器接触过多:

  1. 索引页
      索引页就是其一页面

  程序猿基本上从大学起初就每壹天与计算机为5,通过计算机学习,娱乐,打游戏,Computer的效劳日益的代替了她们对女对象的必要,很好的消遣了他们的寂寥和世俗,所以大家看看就是是从未女对象,技士们也并不会有太多的埋怨,因为她们在互联网世界里可以找到很好的寄托。

image.png



  这个页面就是用ajax来生成的。往下拉动页面,达到边界的时候,Ajax就会自动加载下一页。



image.png


  鼠标选定的那个就是其中一页索引页,一共加载了四页。  
  我们可以看到 四个索引页之间的区别只有
offset参数有区别,其他都是一模一样的。  
  如此来说我们就可以通过修改offset参数来获取任意索引页了。  

    第一页索引页 offset = 0  
    第二页索引页 offset = 20  
    第三页索引页 offset = 40  
    第四页索引页 offset = 60  
  由此可以看出 offset的规律是 跨步20递增。

 

二、和女孩子交流工夫差:

def get_page_index(offset=0):
    """获得索引页内容
    :return 返回json格式数据"""
    url = 'http://www.toutiao.com/search_content/?format=json&keyword=街拍&autoload=true&count=20&cur_tab=3'
    headers = {
            'Host':"www.toutiao.com",
            'Referer':"http://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D"
        }
    params = {'offset': offset}
    html = downloader(url,headers,params)
    return html

  恰恰是因为整日对着Computer,他们的社交才具大幅度退化,变得很宅很封闭,而招致的结果是她们和女孩子交换工夫大致为零,和女人成为爱人的力量都尚未,何况是产生男女朋友,即就是有时能和女子在一同,也是害羞胆怯,不敢主动说道和追求女子,自然就不可能获得女子的鉴赏,不能脱单了。

录像里 用的是
urllib.urlencode()对url参数进行编码,因为大家使用的是requests库,requests能够活动对参数进行编码,所以没需要在动用urllib.urlencode()
  downloader()是空虚出来的下载效能函数。

 

def downloader(url,headers=None,params=None,again_num=3,isBinary=False):
    """根据url下载html
    requests 并不会主动抛出http 状态码异常,
        我们只处理服务器异常也就是状态码为500与600之间。服务器异常则重试3次下载
        服务器异常的情况下主动抛出requs状态码异常
    对超时异常,同样进行重试3次下载
    :param again_num 下载异常时,重复下载次数
    :param  isBinary:是否下载二进制数据,例如图片 True表示下载二进制数据,Flase表示 下载普通html页面
    :return 返回html源码页面"""
    html = None
    try:
        response = requests.get(url, headers=headers, params=params)
        code = response.status_code
        if code == 200:
            html = response.content if isBinary else response.text
        elif 500 <= code < 600:
            response.raise_for_status()
    except requests.HTTPError as e :
        if again_num > 0:
            print ' >>> 服务器异常,下载重试 '
            return downloader(url,headers=headers,params=params,again_num=again_num-1)
    except requests.Timeout as e:
        if again_num > 0:
            print ' >>> 超时异常,下载重试 '
            return downloader(url,headers=headers,params=params,again_num=again_num-1)
    except requests.ConnectionError as e:
        print ' >>> 网咯问题,下载失败 --- ',url
    return html```
  解析索引页,从索引页中提取出来详情页url
Ajax返回的索引页是一个json格式数据。详情页url就包含在json中
![image.png](http://upload-images.jianshu.io/upload_images/4131789-61c8213c9a1f40ba.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  data字段值就是 详情页url集合
![image.png](http://upload-images.jianshu.io/upload_images/4131789-80f1154bda01629f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  acticle_url字段值 就是 详情页url。
  其实 url字段值也是 详情页url 两个是一样的 提取那个都行
![image.png](http://upload-images.jianshu.io/upload_images/4131789-c898c2facc6968d6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

  其实呢,笔者以为就是第3点,你不会扯淡,老是把天聊死,哪个人还会想和你聊天呀是或不是,上面给大家整理了几条土味情话,希望您们能上学学习,交友首先从聊骚初始~

def parse_page_index(html):
“””解析索引页内容,获得信息url
:raise KeyError 当未有多少时候抛出KeyError卓殊
:return 新闻url”””
data = json.loads(html)
#以此地点要加一个 data[‘data’]
# 因为data[‘data’]为空,表示索引页已经到底,未有下1页了。
# 其实下一页仍是能够继续访问,只是重返的全部是再一次数据。
if data and (‘data’ in data) and data[‘data’]:
for item in data[‘data’]:
yield item[‘url’]
else:
raise KeyError(u’未有多少了’)

 美高梅开户网址 2

  我发现当索引页到底的时候也就是最后一页,在网下一页的时候返回的json数据中 data字段值是一个空数据,表示已经到底了。其实还可以在往下一页继续访问,但是返回的json中的data字段值是前面也已经出现过的重复详情页数据。所以我以 data字段值为空数组表示已经到最后一页,不在进行下一页访问,避免获得重复数据。
  视频中用 data.keys()来获得字典的键,其实不用使用data.keys()直接使用 for item in data即可,直接获取的就是 字典的键
2. 抓取详情页
  根据详情页url获得详情页html

“你今后走路能或不能够望着点啊。”——“非要撞在自身心上。”

def get_page_detail(url):
“””得到详细的情况页I音信页)html源码
:return 详情页html源码”””
headers = {
‘Host’:
“www.toutiao.com”,
‘Referer’:
“http://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D”
}
html = downloader(url,headers=headers)
return html

 

  解析详情页,抽取标题,图片urls
  图片的urls是页面中用JavaScript写在html页面中的。这个gallery变量中的 sub_images标签的值就是图片集合。
  所以我们需要从页面中提取出来gallery
![image.png](http://upload-images.jianshu.io/upload_images/4131789-e40d70159a7a48cc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

“你如此完美,正是有三个隐疾。”——“什么毛病?”“缺点本身”

def parse_page_detail(html,url):
“””解析详细的情况页,抽出标题,图片url
:return {url,title,urls} 实际情况页消息 字典会集”””
soup = BeautifulSoup(html,’lxml’)
title = soup.title.string
images_pattern = re.compile(‘var gallery =.?(.?);’,re.S)
result = re.search(images_pattern, html)
if result:
data = json.loads(result.group(1))
if data and (‘sub_images’ in data):
sub_images = data[‘sub_images’]
images = [item[‘url’] for item in sub_images]
# 放到此处回导致重复下载图片,所以 移动到parse_detail中
#
唯有插入数据库成功,才会下载图片,防止因再也运营程序导致对已下载过的图形实行重新的下载。
# for image_url in images:
# download_image(image_url)
return {
‘url’:url,
‘title’:title,
‘images’:images
}

 

  使用正则表达式从页面中提取出gallery的值,并转化为json格式数据,从而提取出图片集合sub_images的值。
  在视频中 下载图片是写在这里的。我个人觉得逻辑上有些不合理。
因为:假如,我们一小时前运行完程序下载图片。一小时后我们再次运行程序下载图片,然而网站数据没有变化仍然是一小时前的数据,或者混杂的有一小时前的数据,那么程序任然会重复的对图片进行下载,并不管图片是否已经下载过,这样就造成了没必要的重复下载。我个人认为,只有详情页信息插入数据库成功,才进行图片下载。因为插入成功表示当前详情页url并未访问过,没访问过就表示图片没下载过。

3. 保存到数据库
  我们将数据保存到 mongodb数据库

“我自然是盐吃多了。”“啊?”——“不然怎么总是闲的想你呀~!”

def save_db(result):
“””保存数据到mongodb中
:return 插入数据库成功重临True,不然重返Flase”””
status = False
try:
if db_table.insert(result):
print ‘保存数据库成功 ‘,result
status = True
except pymongo.errors.DuplicateKeyError:
# 对唯一字段举行再一次插入,pymongo则会抛出这几个错误,并且插入失利
print ‘重复插入’
pass
return status

 

  对已插入过的mongodb文档,进行重复插入会抛出 DuplicateKeyError异常,并插入失败。所有我们捕获这个异常,避免因重复数据的插入导致程序崩溃。
4. 下载图片
  下载图片并保存到当前目录下的 images文件夹内
下载图片

“小编有1人生建议会令你收益毕生哦!”“哪个人生建议啊。”——“那辈子和本身在一道。”

def download_image(url):
“””下载图片并保留到当下文件夹”””
image = downloader(url,isBinary=True)
save_image(image)
print ‘下载图片成功 —- ‘,url

 

保存图片

“喜欢你是件很费劲的事。”——“但本身偏偏喜欢找劳动。”

def save_image(image):
“””保存图片到当前目录下的images文件夹内”””
image_file = ‘images’
image_name = hashlib.md5(image).hexdigest()
# 文件后缀
# imghdr.what(f)再次来到图片文件的格式
# 只接受文件对象,所以用StringIO包装一下
f = StringIO.StringIO(image)
image_suffix = imghdr.what(f)
try:
if not os.path.exists(‘images’):
os.mkdir(‘images’)
file_path = ‘{0}{1}{2}.{3}’.format(image_file, os.path.sep,
image_name, image_suffix)
with open(file_path,’wb’) as f:
f.write(image)
except IOError as e:
print ‘文件操作退步 — ‘,e

 

  使用imghdr.what(file)来获得图片的格式(jpg,gif等)
  imghdr.what(file)接受的是 文件对象,所以我们用StringIO包装下载的图片二进制数据,在内存中生成一个文件对象。
4. 主程序

“吃烧烤是先考海鲜照旧烤肉?” “烤肉” ——“先思量你”

def parse_index(html):
“””解析索引页”””
for url in parse_page_index(html):
page_html = get_page_detail(url)
if page_html:
parse_detail(page_html,url)
def parse_detail(html,url):
“””解析实际情况页”””
result = parse_page_detail(html, url)
stauts = save_db(result)
# 当数据库插入成功的意况下
进行图片下载,制止重新访问导致的再次图片下载
if stauts:
for image_url in result[‘images’]:
download_image(image_url)
def main(offset):
#parse_index 与 parse_detail
是因为main嵌套档期的顺序太多(五层)所以拆分的。
try:
html = get_page_index(offset)
if html:
parse_index(html)
except KeyError as e:
print e.message
print ‘结束’

 

多进程

“等下可以帮本人洗一下事物吗?”“能够啊,洗什么?”——“喜欢自个儿。”

def process_main():
“””多进度,获取前5页数据”””
p = Pool()
offsets = [offset for offset in range(0,100,20)]
p.map_async(main,offsets)
p.close()
p.join()“`

 

总体代码如下:

“冬有尖栗,夏有杧果 你知道四季有何吧?” —— “有您”

#coding=utf-8
"""测试模块"""
import os
import re
import json
import imghdr
import StringIO
import hashlib
import pymongo
import requests
import pymongo.errors
from multiprocessing import Pool
from bs4 import BeautifulSoup
import config

client = pymongo.MongoClient(config.MONGO_URL)
db = client[config.MONGO_DB]
db_table = db[config.MONGO_TABLE]
#创建唯一索引 url
db_table.create_index([('url',pymongo.DESCENDING)],unique=True)

def get_page_index(offset=0):
    """获得索引页内容
    :return 返回json格式数据"""
    url = 'http://www.toutiao.com/search_content/?format=json&keyword=街拍&autoload=true&count=20&cur_tab=3'
    headers = {
            'Host':"www.toutiao.com",
            'Referer':"http://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D"
        }
    params = {'offset': offset}
    html = downloader(url,headers,params)
    return html

def get_page_detail(url):
    """获得详情页I新闻页)html源码
    :return 详情页html源码"""
    print '下载------',url
    headers = {
        'Host': "www.toutiao.com",
        'Referer': "http://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D"
    }
    html = downloader(url,headers=headers)
    return html

def parse_page_index(html):
    """解析索引页内容,获得新闻url
    :raise KeyError 当没有数据时候抛出KeyError异常
    :return 新闻url"""
    data = json.loads(html)
    #这个地方要加一个 data['data']
    # 因为data['data']为空,表示索引页已经到底,没有下一页了。
    # 其实下一页还可以继续访问,只是返回的全部是重复数据。
    if data and ('data' in data) and data['data']:
        for item in data['data']:
            yield item['url']
    else:
        raise KeyError(u'没有数据了')

def parse_page_detail(html,url):
    """解析详情页,抽取标题,图片url
    :return {url,title,urls} 详情页信息 字典集合"""
    soup = BeautifulSoup(html,'lxml')
    title = soup.title.string
    images_pattern = re.compile('var gallery =.*?(.*?);',re.S)
    result = re.search(images_pattern, html)
    if result:
        data = json.loads(result.group(1))
        if data and ('sub_images' in data):
            sub_images = data['sub_images']
            images = [item['url'] for item in sub_images]
            # 放到这里回导致重复下载图片,所以 移动到parse_detail中
            # 只有插入数据库成功,才会下载图片,避免因重新运行程序导致对已下载过的图片进行重复的下载。
            # for image_url in images:
            #     download_image(image_url)
            return {
                'url':url,
                'title':title,
                'images':images
            }

def download_image(url):
    """下载图片并保存到当前文件夹"""
    image = downloader(url,isBinary=True)
    save_image(image)
    print '下载图片成功 ---- ',url

def save_image(image):
    """保存图片到当前目录下的images文件夹内"""
    image_file = 'images'
    image_name = hashlib.md5(image).hexdigest()
    # 文件后缀
    # imghdr.what(f)返回图片文件的格式
    # 只接受文件对象,所以用StringIO包装一下
    f = StringIO.StringIO(image)
    image_suffix = imghdr.what(f)
    try:
        if not os.path.exists('images'):
            os.mkdir('images')
        file_path = '{0}{1}{2}.{3}'.format(image_file, os.path.sep, image_name, image_suffix)
        with open(file_path,'wb') as f:
            f.write(image)
    except IOError as e:
        print '文件操作失败 --- ',e

def save_db(result):
    """保存数据到mongodb中
    :return 插入数据库成功返回True,否则返回Flase"""
    status = False
    try:
        if db_table.insert(result):
            print '保存数据库成功 ',result
            status = True
    except pymongo.errors.DuplicateKeyError:
        # 对唯一字段进行重复插入,pymongo则会抛出这个错误,并且插入失败
        print '重复插入'
        pass
    return status

def downloader(url,headers=None,params=None,again_num=3,isBinary=False):
    """根据url下载html
    requests 并不会主动抛出http 状态码异常,
        我们只处理服务器异常也就是状态码为500与600之间。服务器异常则重试3次下载
        服务器异常的情况下主动抛出requs状态码异常
    对超时异常,同样进行重试3次下载
    :param again_num 下载异常时,重复下载次数
    :param  isBinary:是否下载二进制数据,例如图片 True表示下载二进制数据,Flase表示 下载普通html页面
    :return 返回html源码页面"""
    html = None
    try:
        response = requests.get(url, headers=headers, params=params)
        code = response.status_code
        if code == 200:
            html = response.content if isBinary else response.text
        elif 500 <= code < 600:
            response.raise_for_status()
    except requests.HTTPError as e :
        if again_num > 0:
            print ' >>> 服务器异常,下载重试 '
            return downloader(url,headers=headers,params=params,again_num=again_num-1)
    except requests.Timeout as e:
        if again_num > 0:
            print ' >>> 超时异常,下载重试 '
            return downloader(url,headers=headers,params=params,again_num=again_num-1)
    except requests.ConnectionError as e:
        print ' >>> 网咯问题,下载失败 --- ',url
    return html

def parse_index(html):
    """解析索引页"""
    for url in parse_page_index(html):
        page_html = get_page_detail(url)
        if page_html:
            parse_detail(page_html,url)

def parse_detail(html,url):
    """解析详情页"""
    result = parse_page_detail(html, url)
    stauts = save_db(result)
    # 当数据库插入成功的情况下 进行图片下载,避免重复访问导致的重复图片下载
    if stauts:
        for image_url in result['images']:
            download_image(image_url)
def main(offset):
    #parse_index 与 parse_detail 是因为main嵌套层次太多(5层)所以拆分的。
    try:
        html = get_page_index(offset)
        if html:
            parse_index(html)
    except KeyError as e:
        print e.message
        print '结束'

def process_main():
    """多进程,获取前五页数据"""
    p = Pool()
    offsets = [offset for offset in range(0,100,20)]
    p.map_async(main,offsets)
    p.close()
    p.join()

if __name__ == '__main__':
    process_main()

美高梅开户网址 3

  什么?骚话说不出口,感到自个儿的建议不佳啊?作者就知道你们程序猿没那么会讲话,直接上代码吧,语言骚不了,这就让行动骚起来!

 

  撩妹的前提,一定是要先掌握妹子,你都不打听妹子的特性,怎么聊?干撩吗?这还不比后面发的土味情话呢!所以通过摸底了妹纸喜欢的是怎么着拍片越来越美,怎么着变得更加美,于是就有了以下的python代码!(想询问越多撩妹才具可加群,705673780)

 

代码精通一下

 

import re

from bs4 import BeautifulSoup

from pandas import json

from urllib.parse import urlencode

from requests.exceptions import RequestException

import requests

 

def get_index_page(offset,keyword):

    data={

        ‘offset’: offset,

        ‘format’: ‘json’,

        ‘keyword’: keyword,

        ‘autoload’: ‘true’,

        ‘count’: ’20’,

        ‘cur_tab’: 1

    }

    url = ‘)

    try:

        response = requests.get(url)

        if response.status_code == 200:

            return response.text

        return  None

    except  Exception:

        print(‘请求索引页出错’)

 

def parse_index_page(html):

    data = json.loads(html)

    if data and ‘data’ in data.keys():

        for item in data.get(‘data’):

            yield item.get(‘article_url’)

 

def get_detail_page(url):

    try:

        response = requests.get(url)

        if response.status_code == 200:

            return response.text

        return  None

    except  Exception:

        print(‘请求实际情况页出错’,url)

 

def parse_detail_page(html,url):

    soup = BeautifulSoup(html,’lxml’)

    title = soup.select(‘title’)[0].get_text()

    print(title)

    images_patten = re.compile(‘var gallery = (.*?);’,re.S)

    result = re.search(images_patten,html)

    if result:

        data = json.loads(result.group(1))

        if data and ‘sub_images’ in data.keys():

美高梅开户网址,            sub_images = data.get(‘sub_images’)

            images = [item.get(‘url’) for item in sub_images]

            return {

                ‘title’:title,

                ‘url’:url,

                ‘images’:images,

            }

 

def  main():

    html = get_index_page(0,’街拍’)

    for url in parse_index_page(html):

        html = get_detail_page(url)

        if html:

            result = parse_detail_page(html,url)

            print(result)

 

if __name__ == ‘__main__’:

    main()

 

 

  以上代码输出图集的名称,图集的地方以及每一张图片的url,于是天天分门别类的,给妹纸发消息,完全光彩夺目,有了共同语言,关系就更进一步啦!哈哈,其实那些代码也是自家在网络搜到的呀,那种骚操作仍然留给你们尝尝,小编觉着作者用土味情话挺好的~

 

  希望能和每1位同行一齐交换python更粲焕的手艺,群705673780~
以上代码,大家能够试1试,哈哈

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图