今日头条上搜索“街拍”(http://www.toutiao.com/search/?keyword=街拍)页面后,会出现一系列街拍的图片。
而这些数据如果用之前的爬取静态页面的爬虫是抓取不到数据的。因为今日头条用的是js代码把数据传到前端。那么要如何分析和抓取数据呢?
首先我们用开发者工具查看一下。
发现网页数据是通过Request URL这个地址通过GET方法获取到的,而在 'http://www.toutiao.com/search_content/?' 之后的字符串是由下面这个字典的数据组成的。
于是我们就可以先写出如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import requests from urllib.parse import urlencode from requests.exceptions import RequestException def get_page_index(offset, keyword): data = { 'offset': offset, 'format': 'json', 'keyword': keyword, 'autoload': 'true', 'count': '20', 'cur_tab': '3' } url = 'http://www.toutiao.com/search_content/?' + urlencode(data) try: response = requests.get(url) if response.status_code == 200: return response.text return None except RequestException: print('Error') return None |
这边的 offset 表示获取的数量,而 keyword 表示的是关键词。如果返回的 status_code 为200,则执行 requests.get 获取网页信息,而此时返回的信息是一组json数据。
然后我们通过 json.loads() 将json数据转化为字典用于我们后续的操作。
1 2 3 4 5 6 7 |
import json def parse_page_index(html): data = json.loads(html) if 'data' in data.keys(): for item in data.get('data'): yield item.get('article_url') |
获取到每个页面的url地址之后,再通过遍历这个地址,获取这个url页面下相应的图片的路径,方法与上面一致。
以下是所有的代码。执行后将图库存储在本地文件夹中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
#!/usr/bin/env python3 # -*- coding: utf-8 -*- #抓取今日头条js图库数据 import requests import urllib.request from urllib.parse import urlencode from requests.exceptions import RequestException import json import re import os def get_page_index(offset, keyword): data = { 'offset': offset, 'format': 'json', 'keyword': keyword, 'autoload': 'true', 'count': '20', 'cur_tab': '3' } url = 'http://www.toutiao.com/search_content/?' + urlencode(data) try: response = requests.get(url) if response.status_code == 200: return response.text return None except RequestException: print('Error') return None def parse_page_index(html): data = json.loads(html) if 'data' in data.keys(): for item in data.get('data'): yield item.get('article_url') def get_page_detail(url): try: response = requests.get(url) if response.status_code == 200: return response.text return None except RequestException: print('Error') return None def parse_page_detail(url): html = get_page_detail(url) reg_title = r'<title>(.*?)</title>' reg_json = r'var gallery = (.*?);' title = re.findall(reg_title, html)[0] page_json = re.findall(reg_json, html)[0] data = json.loads(page_json) img_list = [] if 'sub_images' in data.keys(): for item in data.get('sub_images'): img_list.append(item['url']) return {'title': title, 'img': img_list} def save_img(title, img): os.mkdir('F:\\toutiao\\%s\\' % (title)) local = 'F:\\toutiao\\%s\\' % (title) num = 0 print('创建文件夹:%s' % title) for i in img: num +=1 print('%s.jpg 图片下载中...' % num) urllib.request.urlretrieve(i, '%s%s.jpg' % (local, num)) def main(): html = get_page_index(0, '街拍') for url in parse_page_index(html): if 'http://toutiao.com/group' == url[:24]: download_list = parse_page_detail(url) title = download_list['title'] img = download_list['img'] save_img(title, img) else: continue if __name__ == '__main__': main() |
执行结果: