ajax请求数据,并处理返回的数据

 

import requests
from urllib.parse import urlencode
from requests.exceptions import  RequestException
import json
import time
import re
import pymongo
import os
from hashlib import md5

hostName = 'localhost'
databaseName = 'toutiao'
tableName = 'toutiao'
port = 27017
client = pymongo.MongoClient(hostName, port)
db = client[databaseName]
tb = db[tableName]


def save_to_database(result):
    flag = tb.insert(json.loads(result))  # 将json字符串转换为字典类型并insert到数据库insert(key,value# )
    #flag = tb.insert_one(result)
    if flag:
        print("插入到mongodb成功,",result)
        return True
    print("插入到mongodb失败")
    return False


headers = {
        'User-Agent':  'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, '
                       'like Gecko) Chrome/49.0.2623.112 Safari/537.36'
}


def get_page_index(offset, keyword): # 偏移和关键词
    url = 'https://www.toutiao.com/search_content/?'
    data = { # 传入请求参数
        'offset': offset,
        'format': 'json',
        'keyword': keyword,
        'autoload': 'true',
        'count': 20,
        'cur_tab': '1',
        'from': 'search_tab'
    }
    url = url + urlencode(data) # 把参数和url一起拼接起来,作为最终访问的url
    try:
        response = requests.get(url, headers=headers) #相当于发起异步请求
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        print('请求索引页错误')
        return None


def parse_page_index(port_data_str):  # 处理异步请求获得的数据
    if port_data_str:
        port_data_dict = json.loads(port_data_str)  # 将json字符串转为json对象(字典)
        if port_data_dict and 'data' in port_data_dict.keys(): # 如果字典存在且字典中含有名为'data'的key
            for data_item in port_data_dict.get('data'):  # port_data_dict.get('data')得到的是一个列表,列表中有多个字典
                article_url = data_item.get('article_url')  # 从字典中获取key为'article_url'对应的的value
                if article_url: # 去除None
                    yield data_item.get('article_url')
                return 'request_end'


def get_page_detail(url):  # 请求article_info页面
    try:
        response = requests.get(url, headers=headers)
        time.sleep(3)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException as e:
        print('请求详情页错误', url)
        return None

def get_urls():

    for offs in range(0, 300, 20):
        print('offset = ' + str(offs))
        time.sleep(3)
        htm = get_page_index(offs, '街拍')  # 异步请求获取返回的数据
        for url in parse_page_index(htm):  # article_url。处理异步获得的数据(url使用yield属性得到的)
            html = get_page_detail(url)  # 处理article_url
            image_pattern = re.compile('.*?JSON\.parse\("\{(.*?)\]\}"\)', re.S)
            result = re.findall(image_pattern, html)  # 从返回的页面中进行匹配操作
            if result != []:  # 如果匹配到了
                res = result[0].replace('\\', '')  # 把数据进行清洗。http:\\/\\/p3清洗为http://p3。\\/清洗为/
                res = '{' + res + "]}"  # 变成json格式
                json_dict = json.loads(res)  # 将json格式的字符串转为json对象(python中的字典)。
                list_happy = json_dict.get('sub_images')  # 得到一个列表,列表中有多个字典
                for happy in list_happy:  # 处理单个字典
                    happy_url = happy.get('url')
                    #print(happy_url)
                    down_load_image(happy_url)
                    json_str = '{' + '"' + 'src' + '"' + ':' + '"' + happy_url + '"' + '}'  # json格式里,单引号无效,必须用双引号
                    print(json_str)
                    save_to_database(json_str)
            else:
                print('列表为空')


def down_load_image(image_url):
    try:
        response = requests.get(image_url, headers=headers)
        if response.status_code == 200:
            # 如果请求的是网页的url,可以利用response.text,如果请求的是图片的url则利用response.content(二进制内容)
            save_image(response.content)
        else:
            return None
    except RequestException:
        print('请求图片地址出错')


# 如果content的内容是相同的,那么 md5(content).hexdigest()也是相同的,保证了有区别的文件对应不同的文件名
def save_image(content):
    file_path = '{0}/{1}.{2}'.format(os.getcwd(), md5(content).hexdigest(), 'jpg')
    if not os.path.exists(file_path):  # 如果不存在这个文件
        print(file_path, '正在保存')
        with open(file_path, 'wb') as f:  # 'wb'表示保存为文件
            f.write(content)  # 直接保存
            print('文件保存成功:', file_path)
            f.close()

def main():
    get_urls()


if __name__ == '__main__':
    main()



# ) 和 . 都需要加上 \进行转义

 

你可能感兴趣的:(python网络爬虫)