流程框架:

抓取索引页内容:利用requests请求目标站点,得到索引网页HTML代码,返回结果。

抓取详情页内容:解析返回结果,得到详情页的链接,并进一步抓取详情页的信息。

下载图片与保存数据库:将图片下载到本地,并把页面信息及图片URL保存至MongoDB。

开启循环及多线程:对多页内容遍历,开启多线程提高抓取速度。

jiepai_picture.py

'''有些网页直接请求得到的HTML代码,并没有包括在浏览器中直接看到的内容,因为一些信息通过Ajax加载、通过JS渲染生成的,此时要分析网页请求。
本次用到的工具:
网络库:requests、解析库:beautifulsoup和正则表达式、存储数据库:mongoDB、pymongo库。
目标站点分析:
'''
from urllib.parse import urlencode
import requests
from requests.exceptions import RequestException
import json
from bs4 import BeautifulSoup
import re import pymongo
import sys
sys.path.append('D://ASoft/Python/PycharmProjects/pachong/15-分析Ajax请求并抓取今日头条街拍美图') #将自己写的config.py的路径加入到系统路径中以便导入。
from config import *
client = pymongo.MongoClient(MONGO_URL,connect=False) #生成一个Mongo客户端,多进程时候connect=False,每个进程启动时才连接
db = client[MONGO_DB] #定义一个DB import os
from hashlib import md5
from multiprocessing import Pool #引入进程池开启多进程
from json.decoder import JSONDecodeError '''抓取索引页内容'''
def get_page_index(offset,keyword): #使offset和keyword变成可变参数传递进来
#得到网页请求的参数,参数见图1,注意:抓取的是“图集”标题页的内容
data = {
'offset': offset,
'format': 'json',
'keyword': keyword,
'autoload': 'true',
'count': '20',
'cur_tab': '3',
'from': 'gallery' #此属性要加上,否则可能会不会返回标签“图集”的url
# 'pd':''
}
#将字典对象转换为url的请求参数,是urlib库提供的一种编码方法
url = 'https://www.toutiao.com/search_content/?' + urlencode(data) #链接见图2
try:
#利用requests请求这个url
response = requests.get(url)
if response.status_code == 200:
return response.text
else:
return None
except RequestException:
print('请求索引页出错')
return None '''解析索引页信息'''
def parse_page_index(html):
try:
data = json.loads(html) #生成一个json对象。
if data and 'data' in data.keys():
for item in data.get('data'):
yield item.get('article_url') #生成器
except JSONDecodeError:
pass '''得到详情页详细信息'''
def get_page_detail(url):
headers = {
# 'User-Agent': 'Mozilla/4.0(compatible;MSIE 5.5;Windows NT)' #这个user-agent可以,有的user-agent可能会导致爬取到的源码不全。
# 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36'
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko'
}
try:
#利用requests请求这个url,注意此处直接传入url来请求网页内容由于反爬机制可能会得不到网页内容,所以要requests.get方法要加入headers参数。
response = requests.get(url=url,headers=headers)
if response.status_code == 200:
return response.text
else:
return None
except RequestException:
print('请求详情页出错')
return None '''解析详情页信息:根据想要得到的信息,在爬取到的网页源码中搜索想要的信息,找到信息的标签位置,然后利用选择器或正则表达式解析。'''
def parse_page_detail(html,url):
soup = BeautifulSoup(html,'lxml') #由于图片链接信息在原始的网页源代码中可以找到,见图3,所以用Beautiful库解析,以lxml方式解析html
try:
title = soup.select('title')[0].get_text() #得到图片的名称
except IndexError:
print('title获取失败',url)
# images_pattern = re.compile('var gallery = (.*?);', re.S) # 利用正则表达式解析图片链接地址
images_pattern = re.compile('JSON.parse("(.*?)"),', re.S)
# print(html)
result = re.search(images_pattern,html)
if not result:
images_pattern = re.compile('JSON.parse("(.*?)"),', re.S)
result = re.search(images_pattern,html)
if result:
data = json.loads(result.group(1)) #得到包含url的字典
if data and 'sub_images' in data.keys():
sub_images = data.get('sub_images') #得到一个列表,分析得知,列表中包含很多个集合,每个集合中包含一个键为url值为图片链接的键值对。
images = [item.get('url') for item in sub_images] #包含网页街拍中一个组图中每张图片的链接
#下载图片
for image in images:
download_image(image)
#返回图片包含图片名称和链接的字典
return {
'title':title,
'url':url,
'images':images
} #定义一个存储到MONGODB的方法
def save_to_mongo(result):
if db[MONGO_TABLE].insert(result): #如果存储成功
print('存储到MongoDB成功',result)
return True
return False #将图片存储下来
def download_image(url):
print('正在下载',url)
try:
response = requests.get(url)
print('---------')
if response.status_code == 200:
save_image(response.content) #response.content:返回二进制。response.text:返回正常网页源码结果。
return None
except RequestException:
print('请求图片出错',url)
return None #存储为图片
def save_image(content):
#文件路径包括三部分:路径、文件名、后缀。os.getcwd():当前项目的路径。md5(content).hexdigest():防止文件重复,如果图片内容相同则文件名相同。
file_path = '{0}/{1}.{2}'.format(os.getcwd(),md5(content).hexdigest(),'jpg')
if not os.path.exists(file_path):
with open(file_path,'wb') as f:
f.write(content)
f.close() def main(offset):
#得到索引页信息
html_index = get_page_index(offset,KEYWORD)
for url in parse_page_index(html_index): #url是每个详情页的url
# 得到详细页信息
html_detail = get_page_detail(url)
if html_detail:
result = parse_page_detail(html_detail,url) #得到解析后的title,url,images_url
if result:
save_to_mongo(result) #将得到的信息存储到数据库 if __name__ == '__main__':
# main()
#抓取其他索引页
groups = [x * 20 for x in range(GROUP_START,GROUP_END + 1)]
pool = Pool() #声明一个进程池
pool.map(main,groups) config.py
'''把得到的信息存储到MONGODB中。配置信息放到配置文件中。'''
MONGO_URL = 'localhost'
MONGO_DB = 'toutiao'
MONGO_TABLE = 'toutiao' GROUP_START = 1
GROUP_END = 20 KEYWORD = '街拍'

程序执行可能有一些问题,尚待更正。

15-分析Ajax请求并抓取今日头条街拍美图的更多相关文章

  1. 分析Ajax请求并抓取今日头条街拍美图

    项目说明 本项目以今日头条为例,通过分析Ajax请求来抓取网页数据. 有些网页请求得到的HTML代码里面并没有我们在浏览器中看到的内容.这是因为这些信息是通过Ajax加载并且通过JavaScript渲 ...

  2. 2.分析Ajax请求并抓取今日头条街拍美图

    import requests from urllib.parse import urlencode # 引入异常类 from requests.exceptions import RequestEx ...

  3. 分析 ajax 请求并抓取今日头条街拍美图

    首先分析街拍图集的网页请求头部: 在 preview 选项卡我们可以找到 json 文件,分析 data 选项,找到我们要找到的图集地址 article_url: 选中其中一张图片,分析 json 请 ...

  4. python爬虫知识点总结(十)分析Ajax请求并抓取今日头条街拍美图

    一.流程框架

  5. Python爬虫系列-分析Ajax请求并抓取今日头条街拍图片

    1.抓取索引页内容 利用requests请求目标站点,得到索引网页HTML代码,返回结果. 2.抓取详情页内容 解析返回结果,得到详情页的链接,并进一步抓取详情页的信息. 3.下载图片与保存数据库 将 ...

  6. 【Python爬虫案例学习】分析Ajax请求并抓取今日头条街拍图片

    1.抓取索引页内容 利用requests请求目标站点,得到索引网页HTML代码,返回结果. from urllib.parse import urlencode from requests.excep ...

  7. python爬虫之分析Ajax请求抓取抓取今日头条街拍美图(七)

    python爬虫之分析Ajax请求抓取抓取今日头条街拍美图 一.分析网站 1.进入浏览器,搜索今日头条,在搜索栏搜索街拍,然后选择图集这一栏. 2.按F12打开开发者工具,刷新网页,这时网页回弹到综合 ...

  8. Python Spider 抓取今日头条街拍美图

    """ 抓取今日头条街拍美图 """ import os import time import requests from hashlib ...

  9. 爬虫(八):分析Ajax请求抓取今日头条街拍美图

    (1):分析网页 分析ajax的请求网址,和需要的参数.通过不断向下拉动滚动条,发现请求的参数中offset一直在变化,所以每次请求通过offset来控制新的ajax请求. (2)上代码 a.通过aj ...

随机推荐

  1. shell 关于路径查询显示pwd

    获取根目录:dirname $0 cd到根目录:cd `dirname $0` 获取当前目录:pwd 因此,要获取当前目录应该是: cd `dirname $` && pwd 或者 $ ...

  2. 如何用Jupyter notebook打开本地数据集

    首先打开本地Jupyter notebook,出现类似页面并进入网页端Home. 网页端界面类似如下: 需要注意的是,Jupyter notebook只能打开当前目录下的数据集,如csv,所以需要使用 ...

  3. LeetCode算法题-Add Binary(Java实现)

    这是悦乐书的第157次更新,第159篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第16题(顺位题号是67).给定两个二进制字符串,返回它们的总和(也是二进制字符串).输 ...

  4. JDBC复习2

    前面复习了一些基础知识以及如何抽取一些常用的代码,接下来就结合junit4做一个增删改查的小demo 重点是这么几个步骤:1.创建连接 2.编写sql语句 3.编写sql语句的载体 4.如果是Prep ...

  5. 【Linux常见问题】SecureCRT 终端连接密钥交换失败错误

    SecureCRT 终端软件连接linux操作系统,出现如下错误: 英文描述:Key exchange failed. No compatible key exchange method. The s ...

  6. Python 进程管理工具 Supervisor 使用教程

    Supervisor 是基于 Python 的进程管理工具,只能运行在 Unix-Like 的系统上,也就是无法运行在 Windows 上.Supervisor 官方版目前只能运行在 Python 2 ...

  7. node基础—http模块

    在浏览器输入存在的网址的一个交互过程 1.用户通过浏览器发送一个http的请求到指定的主机 2.服务器接收到该请求,对该请求进行分析和处理 3.服务器处理完成以后,返回对应的数据到用户机器 4.浏览器 ...

  8. C. Meaningless Operations Codeforces Global Round 1 异或与运算,思维题

    C. Meaningless Operations time limit per test 1 second memory limit per test 256 megabytes input sta ...

  9. 【BZOJ2117】 [2010国家集训队]Crash的旅游计划

    [BZOJ2117] [2010国家集训队]Crash的旅游计划 Description 眼看着假期就要到了,Crash由于长期切题而感到无聊了,因此他决定利用这个假期和好友陶陶一起出去旅游. Cra ...

  10. [SDOI2008]递归数列

    嘟嘟嘟 裸的矩阵快速幂,构造一个\((k + 1) * (k + 1)\)的矩阵,把sum[n]也放到矩阵里面就行了. #include<cstdio> #include<iostr ...