爬虫:今日头条

知识点:

  1.urlencode的使用

  2.md5加密方法

  3.os的使用

  4.json格式的get方法

遇到的问题:

  1.返回的json数据为空:原因,没有添加headers和cookie

import time
import requests
import urllib.parse
def get_page(offset,timestamp):
    parms={
        'aid':'24',
        'app_name':'web_search',
        'offset':offset,
        'format':'json',
        'keyword':'街拍',
        'autoload':'true',
        'count':'20',
        'en_qc':'1',
        'cur_tab':'1',
        'from':'search_tab',
        'pd':'synthesis',
        'timestamp':timestamp,
    }

    url='https://www.toutiao.com/api/search/content/?'+urllib.parse.urlencode(parms)


    try:
        response = requests.get(url)
        if response.status_code==200:
            print(response.json())
            return response.json()
    except requests.ConnectionError:
        print('请求失败')
        return None

if __name__ == '__main__':
    get_page(20,int(time.time()))

结果:

{'count': 0, 'return_count': 0, 'query_id': '6537385837821170952', 'has_more': 0, 'request_id': '20200203144241010014017021172B7CF7', 'search_id': '20200203144241010014017021172B7CF7', 'cur_ts': 1580712161, 'offset': 40, 'message': 'success', 'pd': 'synthesis', 'show_tabs': 1, 'keyword': '街拍', 'city': '永州', 'log_pb': {'impr_id': '20200203144241010014017021172B7CF7', 'is_incognito': 0}, 'data': None, 'data_head': [{'challenge_code': 1366, 'cell_type': 71, 'keyword': '街拍', 'url': 'sslocal://search?keyword=%E8%A1%97%E6%8B%8D&from=&source=search_tab'}], 'ab_fields': None, 'latency': 0, 'search_type': 2, 'tab_rank': None, 'temp_type': 0, 'tab_list': None}

正确结果:

import urllib.parse
import os
from hashlib import md5


headers={
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
}

cookie={

    'Cookie':' tt_webid=6789077713942971916; s_v_web_id=k65z596n_stTrkCwT_ni5x_4sJa_BH3v_HlSjP1Rsc1ko; WEATHER_CITY=%E5%8C%97%E4%BA%AC; tt_webid=6789077713942971916; csrftoken=b898a5247b610a1bd24735bbdccc8a8a; __tasessionId=tbdg6xx8b1580707187238'

}
def get_page(offset,timestamp):
    parms={
        'aid':'24',
        'app_name':'web_search',
        'offset':offset,
        'format':'json',
        'keyword':'街拍',
        'autoload':'true',
        'count':'20',
        'en_qc':'1',
        'cur_tab':'1',
        'from':'search_tab',
        'pd':'synthesis',
        'timestamp':timestamp,
    }

    url='https://www.toutiao.com/api/search/content/?'+urllib.parse.urlencode(parms)


    try:
        response = requests.get(url,headers=headers,cookies=cookie)
        if response.status_code==200:
            print(response.json())
            return response.json()
    except requests.ConnectionError:
        print('请求失败')
        return None

if __name__ == '__main__':
    get_page(20,int(time.time()))


#结果
{'count': 20, 'return_count': 20, 'query_id': '6537385837821170952', 'has_more': 1, 'request_id': '202002031444450100120260661F2BF201',
'search_id': '202002031444450100120260661F2BF201', 'cur_ts': 1580712286,
'offset': 40, 'message': 'success', 'pd': 'synthesis', 'show_tabs': 1, 'keyword': '街拍', 'city': '永州', 'tokens': ['街拍'],
'log_pb': {'impr_id': '202002031444450100120260661F2BF201', 'is_incognito': 0},
'data': [{'abstract': '', 'app_info': {'db_name': 'R_SITE', 'page_type': '1', 'query_type': 'SearchAggregationInternalQueryType'},
'article_url': 'http://toutiao.com/item/6786802624487227908/', 'behot_time': '1580175623', 'comment_count': 0, '。。。。等等等
 

完整代码:

# -*- coding:utf-8 -*-
import time
import requests
import urllib.parse
import os
from hashlib import md5

headers={
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
}

cookie={

    'Cookie':' tt_webid=6789077713942971916; s_v_web_id=k65z596n_stTrkCwT_ni5x_4sJa_BH3v_HlSjP1Rsc1ko; WEATHER_CITY=%E5%8C%97%E4%BA%AC; tt_webid=6789077713942971916; csrftoken=b898a5247b610a1bd24735bbdccc8a8a; __tasessionId=tbdg6xx8b1580707187238'

}
def get_page(offset,timestamp):
    parms={
        'aid':'24',
        'app_name':'web_search',
        'offset':offset,
        'format':'json',
        'keyword':'街拍',
        'autoload':'true',
        'count':'20',
        'en_qc':'1',
        'cur_tab':'1',
        'from':'search_tab',
        'pd':'synthesis',
        'timestamp':timestamp,
    }

    url='https://www.toutiao.com/api/search/content/?'+urllib.parse.urlencode(parms)    #知识点1,urlencode的使用


    try:
        response = requests.get(url,headers=headers,cookies=cookie)
        if response.status_code==200:

            return response.json()
    except requests.ConnectionError:
        print('请求失败')
        return None



def get_image(myjson):
    if myjson.get('data'):                        #知识点2,字典的get方法
        for item in myjson.get('data'):
            if item.get('title'):
                title=item.get('title')

                image_list=item.get('image_list')
                for image in image_list:
                    # print(image.get('url'))
                    if image:
                        image_url=image.get('url')

                        yield{                        #知识点3,yield生成器
                            'title':title,
                            'image':image_url
                        }
def save_image(item):
    if not os.path.exists(item.get('title')):                #知识点4,os模块
        os.mkdir(item.get('title'))
    try:
        response=requests.get(url=item.get('image'),headers=headers)
        if response.status_code==200:
            file_path='{0}/{1}.{2}'.format(item.get('title'),md5(response.content).hexdigest(),'.jpg')            #知识点5,MD5加密
if not os.path.exists(file_path): with open(file_path,'wb')as fp:                        #知识点6,文件读写方法 fp.write(response.content) else: print('文件已下载',file_path) else: print('访问失败') except requests.ConnectionError: print('下载失败') from multiprocessing.pool import Pool def main(offset): json = get_page(offset,int(time.time())) for item in get_image(json): print(item) save_image(item) GROUP_START = 1 GROUP_END = 20 if __name__ == '__main__': pool = Pool() groups = ([x * 20 for x in range(GROUP_START, GROUP_END + 1)]) pool.map(main, groups) pool.close() pool.join()

知识点回顾

一、urlencode的使用

import urllib.parse


url='http://www.baidu.com/'

params={
    'kw':'美女',
    'time':'time',
}

query_string=urllib.parse.urlencode(params)

new_url=url+query_string
print(new_url)


#结果
http://www.baidu.com/kw=%E7%BE%8E%E5%A5%B3&time=time

二、字典的get方法

my_dict={
    'title':'街拍美女',
    'image':'http://www.baidu.com/'
}

print(my_dict.get('title'))
print(my_dict.get('image'))


#结果
街拍美女
http://www.baidu.com/

三、yield

def foo():
    print('start..')
    while True:
        res= yield 4
        print('res:',res)

r= foo()
print(type(r))
print(next(r))
print('*'*20)
print(next(r))


#结果
<class 'generator'>
start..
4
********************
res: None
4


#代码解释:
1.程序开始,遇到yield关键字,foo函数并没有真正执行,而是得到一个生成器对象 r
2.当执行next方法的时候,函数开始执行,打印了start,进入while循环
3.程序遇到关键字yield,返回一个 4 ,此时res并没有被赋值 ,此时next执行完成,输出了前面两行
4.程序执行打印20个*
5.继续执行next方法,不过这次跟上次不同,这次是从上次停止的地方开始继续执行,所以此时打印出来res的结果,因为前面没有把4给res,所以此时res是空的
6.程序又一次进入while 返回4 所以又打印了一次 4


#要点:
1.带yield的函数是一个生成器
2.要执行这个函数需要调用next方法,这一次的next开始的地方是接着上一次的next停止的地方执行的

四、os模块

import os
current_cd=os.getcwd()
print(current_cd)

#结果
C:UsersegonPycharmProjectspyCrawlerAjax练习

参考见:https://www.cnblogs.com/yufeihlf/p/6179547.html

五、MD5加密

import hashlib

m=hashlib.md5()
m.update(b'123')
print(m.hexdigest())

#结果
202cb962ac59075b964b07152d234b70

update(arg)传入arg对象来更新hash的对象。必须注意的是,该方法只接受byte类型,否则会报错。这就是要在参数前添加b来转换类型的原因。

常见用法:
print(hashlib.md5(b'123').hexdigest())


#对中文进行md5需要转码
data='你好世界'
print(hashlib.md5(data.encode('utf-8')).hexdigest())


参考:https://www.cnblogs.com/lanston1/p/11025881.html

六、文件读写模式

w 以写方式打开,
W 文件若存在,首先要清空,然后(重新)创建
a 以追加模式打开 (从 EOF 开始, 必要时创建新文件)
r+ 以读写模式打开
w+ 以读写模式打开 (参见 w )
a+ 以读写模式打开 (参见 a )
rb 以二进制读模式打开
wb 以二进制写模式打开 (参见 w )
ab 以二进制追加模式打开 (参见 a )
rb+ 以二进制读写模式打开 (参见 r+ )
wb+ 以二进制读写模式打开 (参见 w+ )
ab+ 以二进制读写模式打开 (参见 a+ )
原文地址:https://www.cnblogs.com/hongweijiang/p/12256015.html