流程框架:

抓取索引页内容:利用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. Selenium Webdriver 中的 executeScript 使用方法

    1.使用executeScript 返回一个WebElement . 下例中我们将一个浏览器中的JavaScript 对象返回到客户端(C#,JAVA,Python等). IWebElement el ...

  2. 介绍一个比较了各种浏览器对于HTML5 等标准支持程度的网站

    可以选择浏览器种类,版本,比较的功能 网站地址:https://caniuse.com/#comparison

  3. LeetCode算法题-Plus One(Java实现)

    这是悦乐书的第156次更新,第158篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第15题(顺位题号是66).给定一个非空数字数组来表示一个非负整数,并给其加1.该数组已 ...

  4. Java JDK与JRE

    JDK与JRE JDK(Java Development Kit):Java开发工具包.包含JRE中的所有内容,以及用于开发小应用程序和应用程序的编译器和调试器等工具. JRE(Java Runtim ...

  5. 自定义Chrome浏览器

    一.全局 自用备份,窗体透明化.要添加对应网站的窗体class到对应的位置 /*主页背景*/ /*https://images.cnblogs.com/cnblogs_com/AardWolf/135 ...

  6. 【夯实Ruby基础】Ruby快速入门

    本文地址: http://www.cnblogs.com/aiweixiao/p/6664301.html 文档提纲 扫描关注微信公众号 1.Ruby安装 1.1)[安装Ruby] Linux/Uni ...

  7. nodejs websocket

    <script src="https://cdn.socket.io/socket.io-1.4.5.js"></script> <script ty ...

  8. React项目中那些奇怪的写法

    1.在一个React组件里看到一个奇怪的写法: const {matchs} = this.props.matchs; 原来,是解构赋值,虽然听说过,但是看起来有点奇怪 下面做个实验: <scr ...

  9. 新手PHP连接MySQL数据库出问题(Warning: mysqli_connect(): (HY000/1045): Access denied for user 'root'@'localhost' (using password: YES))

    我用的环境是wampServer集成的软件包 在php连接MySQL数据库的时候老是出现这个问题Warning: mysqli_connect(): (HY000/1045): Access deni ...

  10. 【转】APK反编译

    学习和开发Android应用有一段时间了,今天写一篇博客总结一下Android的apk文件反编译.我们知道,Android应用开发完成之后,我们最终都会将应用打包成一个apk文件,然后让用户通过手机或 ...