python爬取网页数据 ajax_python 爬取虎嗅网-post方法抓取ajax动态页面(上)

本文主要是介绍python爬取网页数据 ajax_python 爬取虎嗅网-post方法抓取ajax动态页面(上),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、分析背景:

1,为什么要选择虎嗅

「关于虎嗅」虎嗅网创办于 2012 年 5 月,是一个聚合优质创新信息与人群的新媒体平台。

2,分析内容

分析虎嗅网 5 万篇文章的基本情况,包括收藏数、评论数等;

发掘最受欢迎和最不受欢迎的文章及作者;

分析文章标题形式(长度、句式)与受欢迎程度之间的关系;

展现近些年科技互联网行业的热门词汇

3,分析工具:

python3.6

scrapy

MongoDB

Matplotlib

WordCloud

Jieba

数据抓取

使用scrapy抓取了虎嗅网的主页文章,文章抓取时间为2012年建站至2018年12月7日共计约5 万篇文章。抓取 了 8 个字段信息:文章标题、作者、发文时间、评论数、收藏数、摘要,文章链接和文章内容。

1.目标网站分析

这是要爬取的 网页界面,可以看到是通过 AJAX 加载的。

1448266-20190220115902638-782590266.png

1448266-20190220120554122-1990448788.png

F12打开开发者工具,可以看到 URL 请求是 POST 类型,下拉到底部查看 Form Data,表单需提交参数只有 3 项。经尝试, 只提交 page 参数就能成功获取页面的信息,其他两项参数无关紧要,所以构造分页爬取非常简单。

1448266-20190220120619810-1739977823.png

1448266-20190220115708012-1974366334.png

接着,切换选项卡到 Preview 和 Response 查看网页内容,可以看到数据都位于 data 字段里。total_page 为 2119,表示一共有 2119 页的文章内容,每一页有 25 篇文章,总共约 5 万篇,也就是我们要爬取的数量。

Scrapy介绍

Scrapy 是用纯 Python 实现一个为了爬取网站数据、提取结构性数据而编写的应用框架,用途非常广泛。框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非常之方便。Scrapy 使用了 Twisted['twɪstɪd](其主要对手是 Tornado)异步网络框架来处理网络通讯,可以加快我们的下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵活的完成各种需求。

scrapy是如何帮助我们抓取数据的呢?

1448266-20190220123326236-1503912445.png

scrapy框架的工作流程:

1448266-20190220123423715-764885681.png

1.首先Spiders(爬虫)将需要发送请求的url(requests)经ScrapyEngine(引擎)交给Scheduler(调度器)。

2.Scheduler(排序,入队)处理后,经ScrapyEngine,DownloaderMiddlewares(可选,主要有User_Agent, Proxy代理)交给Downloader。

3.Downloader向互联网发送请求,并接收下载响应(response)。将响应(response)经ScrapyEngine,SpiderMiddlewares(可选)交给Spiders。

4.Spiders处理response,提取数据并将数据经ScrapyEngine交给ItemPipeline保存(可以是本地,可以是数据库)。

5. 提取url重新经ScrapyEngine交给Scheduler进行下一个循环。直到无Url请求程序停止结束。

实现代码

创建项目

scrapy startproject 项目名

scrapy genspider 爬虫名 网址

1448266-20190220123954627-1292539651.png

1448266-20190220124047639-806621932.png

这里,首先定义了一个 HuxiuV1Spider 主类,整个爬虫项目都主要在该类下完成。 接着,可以将爬虫基本的一些基本配置,比如:Headers、代理等设置写在下面的 headers 属性中。

1448266-20190220140630817-37345510.png

由于 URL 是 POST 请求,所以我们还需要使用formdata={'page':str(i)}来将FormData中的表单参数添加进去,这里我们需要设置为 POST;formdata 是 POST 请求表单参数,只需要添加一个 page 参数即可。接着,通过 callback 参数定义一个 parse() 方法,用来解析 URL 成功后返回的 Response 响应。在后面的 parse() 方法中,可以使用 re,xpath提取响应中的所需内容。

1448266-20190220141549091-1041311136.png

1448266-20190220141624509-764169822.png

这里我们利用正则表达式提取出文章标题,链接,作者等所需信息,这里将数据保存为list数据,便于后续存储到mongo数据库中。

成功得到所需数据,然后就可以保存了,可以选择输出为csv,MySQL,mongoDB,这里我们选择mongoDB数据库

1448266-20190220142734740-1680298437.png

创建数据库文件的存放位置

因为启动 mongodb 服务之前需要必须创建数据库文件的存放文件夹,否则命令不会自 动创建,而且不能启动成功。

1. 在文件夹下,新建data文件夹,在data文件下新建db文件夹

1448266-20201021185246673-584279574.png

2.指定db 目录并启动

在命令行窗口中,首先来了 bin 路径,然后输入命令: mongod--dbpathD:\mongo\data\db

1448266-20201021185400839-1676364807.png

ContractedBlock.gif

ExpandedBlockStart.gif

1 #-*- coding: utf-8 -*-

2 #from scrapy.spider import CrawlSpider

3 from selenium importwebdriver4 importtime5 from scrapy.linkextractors importLinkExtractor6 from scrapy.spiders importCrawlSpider, Rule7 #import json

8 from datetime importdatetime9 from ..items importHuxiuItem10 from scrapy.http importFormRequest11 importscrapy12 importjson,re13 classHuxiuV1Spider(scrapy.Spider):14 name = 'huxiu_v1'

15 allowed_domains = ['huxiu.com']16 headers={17 'Referer': 'https://www.huxiu.com/index.php/',18 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'

19 }20 #post

21 #Form data

22 #page: 2

23 defstart_requests(self):24 url='https://www.huxiu.com/v2_action/article_list'

25 requests=[]26 for i in range(2,2119):27 formdata={28 'page':str(i)29 }30 request=FormRequest(url,callback=self.parse,formdata=formdata,headers=self.headers)31 requests.append(request)32 returnrequests33 defparse(self, response):34 js=json.loads(response.body.decode())35 #print(js)

36 req =str(js)37 idd = re.findall(r'data-aid="(.*?)">', req)#未处理的url(id)

38 title = re.findall(r'class="transition msubstr-row2" target="_blank">(.*?)', req)#标题

39 auth = re.findall(r'class="author-name">(.*?)', req)#作者

40 pinglun = re.findall(r'(.*?)', req)#评论

41 shoucang = re.findall(r'(.*?)', req)#收藏

42 zhaiyao = re.findall(r'

(.*?)
', req)#未处理的摘要

43 digect = []#摘要

44 for i inzhaiyao:45 s = i[34:-12]46 if 'span' ini:47 s = i[104:-12]48 digect.append(s)49 #print(digect)

50 #print(title)

51 detail_url=[]52 for i inidd:53 burl = 'https://www.huxiu.com/article/{}.html'.format(i)54 detail_url.append(burl)55 #print(detail_url)

56 for i inrange(len(idd)):57 item=HuxiuItem()58 item['title']=title[i]59 item["auth"]=auth[i]60 item['detail_url']=detail_url[i]61 item['pinglun']=pinglun[i]62 item['shoucang']=shoucang[i]63 item['zhaiyao']=digect[i]64 print(detail_url[i])65 #yield item

66 yield scrapy.Request(url=detail_url[i],meta={'meta1':item},callback=self.pasre_item)67 defpasre_item(self,response):68 meta1=response.meta['meta1']69 #print('hello')

70 time=response.xpath('//span[@class="article-time pull-left"]/text()|//span[@class="article-time"]/text()').extract()71 content=response.xpath('//div[@class="article-content-wrap"]/p/text()|//div[@class="article-content-wrap"]/div/text()|//div[@class="article-content-wrap"]/div/span/text()').extract()72 print(time)73 ssss=''

74 for i incontent:75 ssss+=i76 #num = response.xpath('//div[@class="author-article-pl"]/ul/li/a/text()')

77 #wnums=''

78 #for i in num:

79 #wnums = i[:-3]

80 #print(wnums)

81 for i inrange(len(time)):82 item =HuxiuItem()83 item['title']=meta1['title']84 item['auth']=meta1['auth']85 item['detail_url']=meta1['detail_url']86 item['pinglun']=meta1['pinglun']87 item['shoucang']=meta1['shoucang']88 item['zhaiyao']=meta1['zhaiyao']89 item['time']=time[i]90 #item['wnums']=num

91 item['content']=ssss92

93 yield item

spider

ContractedBlock.gif

ExpandedBlockStart.gif

1 #-*- coding: utf-8 -*-

2

3 #Define here the models for your scraped items

4 #5 #See documentation in:

6 #https://doc.scrapy.org/en/latest/topics/items.html

7

8 importscrapy9

10

11 classHuxiuItem(scrapy.Item):12 #define the fields for your item here like:

13 #name = scrapy.Field()

14 title =scrapy.Field()15 auth =scrapy.Field()16 detail_url =scrapy.Field()17 pinglun =scrapy.Field()18 shoucang =scrapy.Field()19 zhaiyao =scrapy.Field()20 time =scrapy.Field()21 content=scrapy.Field()22 #wnums=scrapy.Field()

item

ContractedBlock.gif

ExpandedBlockStart.gif

1 importpymongo2

3 classHuVPipeline(object):4 def __init__(self):5 self.client=pymongo.MongoClient()#链接Mongodb数据库

6 self.db=self.client['huxiuv3']#新建数据库

7 defprocess_item(self, item, spider):8 self.db['huxiu_v5'].insert(dict(item))#第一种方法 #将数据存放到插入到表中

9 return item

pipelines

ContractedBlock.gifsetting

以上,就完成了数据的获取。有了数据我们就可以着手分析,不过这之前还需简单地进行一下数据的清洗、处理。

1448266-20190220133512303-1922767318.png

这篇关于python爬取网页数据 ajax_python 爬取虎嗅网-post方法抓取ajax动态页面(上)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/324012

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表