关键词采集文章(《人民日报》爬虫文章反馈:遍历文件夹将搜索结果爬取下来即可 )

优采云 发布时间: 2021-09-05 03:26

  关键词采集文章(《人民日报》爬虫文章反馈:遍历文件夹将搜索结果爬取下来即可

)

  上一期《人民日报》的爬虫文章发布了,收到了很好的反馈。文章中的爬虫代码确实帮助了很多人。我很高兴。

  在和读者交流的过程中,我也发现了一些比较常见的需求,就是根据关键词过滤news文章。

  我最初的想法是在爬取所有文章数据的基础上遍历文件夹,然后过滤掉正文中收录关键词的文章。

  如果你下载了完整的新闻资料,这个方法无疑是最方便快捷的。但如果不是,那么先爬取所有数据,再筛选符合条件的数据无疑是浪费时间。

  本文文章我将介绍两种方法,一种是根据关键词过滤已有数据,另一种是利用人民网的搜索功能对关键词的搜索进行爬取结果。

  1. 爬取关键词搜索结果

  最近有读者问我问题,我发现人民网有搜索功能()。

  

  所以只需要根据关键词进行搜索,然后向下爬取搜索结果即可。

  1.1 分析页面

  这里简单教大家分析网页的大体思路。

  1.1.1 分析网页主要看什么1.1.2 如何使用浏览器的开发者工具

  具体操作也很简单。按F12打开开发者工具,切换到网络,刷新网页。可以看到列表中有很多请求。

  

  有图片、js代码、css样式、html源代码等各种请求

  点击对应的请求项后,您可以在Preview或Response中预览请求的数据内容,看是否收录您需要的数据。

  

  当然可以一一检查,也可以使用顶部的过滤器过滤请求类型(一般情况下,我们需要的数据可以在XHR和Doc中找到)

  

  找到对应的请求后,可以切换到headers查看请求的请求头信息。

  

  如图所示,主要有四个重点领域。

  请求 URL:请求的链接。爬虫请求的url需要在这里读取。不要只复制浏览器地址栏中的 URL。请求方法:有两种类型的请求方法:GET 和 POST。爬虫代码中是使用requests.get()还是requests.post()要与此一致,否则可能无法正确获取数据。 Request Headers:请求头,服务器会根据这个判断谁在访问网站。一般需要在爬虫请求头中设置User-Agent(有的网站可能需要判断Accept、Cookie、Referer、Host等,根据具体情况设置)将爬虫伪装成普通浏览器用户并防止其被反爬虫机制拦截。 Request Payload:请求参数,服务器会根据这些参数决定返回给你哪些数据,比如页码,关键词等,找到这些参数的规则,你可以通过构造这些参数数据。 1.1.3 服务器返回的数据有哪些形式

  一般情况下有两种格式,html和json。接下来我就简单教大家如何判断。

  HTML 格式

  一般情况下,它会出现在过滤条件中的Doc类型中,也很容易区分。它在响应中查看。整篇文章都打上了这种标签。

  

  如果你确定html源码中收录了你需要的数据(所以,因为有些情况下数据是通过js代码动态加载的,直接解析源码是找不到数据的)

  在Elements中,你可以通过左上角的箭头按钮,快速方便的定位到网页上数据所在的标签(我就不赘述了,自己试试就明白了) .

  

  大多数人从解析html开始学习爬虫,所以应该对它比较熟悉。解析方法很多,比如正则表达式、BeautifulSoup、xpath等。

  Json 格式

  如前所述,在某些情况下,数据不是直接在html页面返回,而是通过其他数据接口动态请求加载。这就导致了一些同学刚开始学习爬虫的时候,在网页上分析的时候,标签路径是可以的,但是请求代码的时候却找不到标签。

  这种动态加载数据的机制叫做Ajax,有兴趣的可以自行搜索。

  ajax请求在请求类型上一般都是XHR,数据内容一般以json格式显示。 (有同学不知道怎么判断一个请求是ajax还是数据是不是json,我该怎么做呢?这里有一个简单的判断方法。在Preview中看看是不是类似下面的表格,大括号, 键值对 { "xxx": "xxx"}, 一个可以开闭的小三角形)

  

  这种类型的请求返回的数据是json格式的,可​​以直接用python中的json库解析,非常方便。

  上面给大家简单介绍了如何分析网页,如何抓包。希望对大家有帮助。

  贴上正题,通过上面介绍的方法,我们不难知道人民网的搜索结果数据是通过Ajax发送的。

  

  请求方法是POST。请求链接、请求头、请求参数都可以在Headers中查看。

  

  在参数中,我们可以看到key应该是我们搜索到的关键词,page是页码,sortType是搜索结果的排序方式等等,知道这些规则,所以我们可以自己构造请求。

  1.2 探索防爬机制

  一般网站会设置一些防爬机制来防止攻击。下面简单介绍一些常见的防爬机制及对策。

  1.2.1 用户代理

  服务器会根据请求头中的User-Agent字段判断用户访问什么,如:

  Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36

  此处收录有关浏览器和计算机系统的一些基本信息。如果你的python爬虫代码没有设置这个字段值,会默认为python,这样服务器就可以大致判断请求是爬虫发起的,然后选择是否拦截。

  解决方法也比较简单,就是用浏览器访问时,复制请求头中的User-Agent值,在代码中设置。

  1.2.2 推荐人

  一些网站 资源添加了反水蛭链接。也就是说,服务器在处理请求的时候,会判断Referer的值。只有在指定站点发起请求时,服务器才会允许返回数据(这样可以防止资源被其他网站盗用和使用)。

  响应方式也很简单,浏览器访问时复制请求头中的Referer值即可。

  1.2.3 饼干

  有些网站可能需要登录账号才能访问一些数据,此处使用cookie值。

  如果不设置cookie,可以设置未登录时访问的cookie,登录账号后设置cookie,数据结果可能不同。

  响应方式因网站而异。如果您无需设置 cookie 即可访问,那么请不要在意;如果需要设置访问,则根据情况(是否要登录,是否要成为会员等)复制浏览器请求header中的cookie值进行设置。

  1.2.4 JS参数加密

  在请求参数中,可能会有一些类似乱码的参数。你不知道它是什么,但它非常重要。它不是时间戳。不填写或随便填写,都会导致请求失败。

  这种情况比较困难。这是js算法加密后的参数。如果要自己构建,则需要模拟整个参数加密算法。

  但是由于这个加密过程是由前端完成的,所以完全可以得到加密算法的js代码。如果你了解一些前端知识,或者逆向Js,可以尝试破解。

  我个人不推荐这个。一是破解麻烦,二是可能违法。

  或者,使用 selenium 或 ``pyppeteer` 自动抓取。不香。

  1.2.5 抓取频率限制

  如果长时间频繁抓取数据,网站服务器的压力会很大,普通人不可能访问这么高强度的访问(比如每次十几次)第二个网站) 乍一看,爬虫做到了。因此,服务器通常会设置访问频率阈值。例如,如果一分钟内发起的请求超过300个,则视为爬虫,限制访问其IP。

  响应,我建议如果你不是特别赶时间,可以设置一个延迟功能,每次抓取数据时随机休眠几秒,让访问频率降低到阈值以下,并且降低服务器访问压力。减少 IP 阻塞的机会。

  1.2.6 其他

  有一些不太常见但也更有趣的防攀爬机制。让我给你举几个例子。

  以上是一些常见的防爬机制,希望对大家有帮助。

  经过测试,人民网的防爬机制并不是特别严格。如果参数设置正确,抓取基本不会受到限制。

  但如果是数据量比较大的爬取,最好设置爬取延迟和断点连续爬取功能。

  1.3 改进代码

  首先导入所需的库。

  本爬虫代码中各个库的用处已在评论中标明。

  import requests # 发起网络请求

from bs4 import BeautifulSoup # 解析HTML文本

import pandas as pd # 处理数据

import os

import time # 处理时间戳

import json # 用来解析json文本

  发起网络请求函数fetchUrl

  代码注释中已经标注了函数的用途和三个参数的含义,返回值为json类型数据

  '''

用于发起网络请求

url : Request Url

kw : Keyword

page: Page number

'''

def fetchUrl(url, kw, page):

# 请求头

headers={

"Accept": "application/json, text/plain, */*",

"Content-Type": "application/json;charset=UTF-8",

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36",

}

# 请求参数

payloads = {

"endTime": 0,

"hasContent": True,

"hasTitle": True,

"isFuzzy": True,

"key": kw,

"limit": 10,

"page": page,

"sortType": 2,

"startTime": 0,

"type": 0,

}

# 发起 post 请求

r = requests.post(url, headers=headers, data=json.dumps(payloads))

return r.json()

  数据分析函数parseJson

  解析json对象,然后将解析后的数据包装成数组返回

  def parseJson(jsonObj):

#解析数据

records = jsonObj["data"]["records"];

for item in records:

# 这里示例解析了几条,其他数据项如末尾所示,有需要自行解析

pid = item["id"]

originalName = item["originalName"]

belongsName = item["belongsName"]

content = BeautifulSoup(item["content"], "html.parser").text

displayTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(item["displayTime"]/1000))

subtitle = item["subtitle"]

title = BeautifulSoup(item["title"], "html.parser").text

url = item["url"]

yield [[pid, title, subtitle, displayTime, originalName, belongsName, content, url]]

  数据保存功能saveFile

  '''

用于将数据保存成 csv 格式的文件(以追加的模式)

path : 保存的路径,若文件夹不存在,则自动创建

filename: 保存的文件名

data : 保存的数据内容

'''

def saveFile(path, filename, data):

# 如果路径不存在,就创建路径

if not os.path.exists(path):

os.makedirs(path)

# 保存数据

dataframe = pd.DataFrame(data)

dataframe.to_csv(path + filename + ".csv", encoding='utf_8_sig', mode='a', index=False, sep=',', header=False )

  主要功能

  if __name__ == "__main__":

# 起始页,终止页,关键词设置

start = 1

end = 3

kw = "春节"

# 保存表头行

headline = [["文章id", "标题", "副标题", "发表时间", "来源", "版面", "摘要", "链接"]]

saveFile("./data/", kw, headline)

#爬取数据

for page in range(start, end + 1):

url = "http://search.people.cn/api-search/elasticSearch/search"

html = fetchUrl(url, kw, page)

for data in parseJson(html):

saveFile("./data/", kw, data)

print("第{}页爬取完成".format(page))

# 爬虫完成提示信息

print("爬虫执行完毕!数据已保存至以下路径中,请查看!")

print(os.getcwd(), "\\data")

  以上就是这个爬虫的全部代码。您可以在此基础上对其进行修改和使用。仅供学习交流使用,请勿用于非法用途。

  注:文字爬取的代码这里就不写了。一个是人网文章文字爬取的功能在之前的文章文章中已经写好了。如果需要,可以自己集成代码;另一个是,抓取文本会引入一些其他问题,例如链接失败,文章来自不同的网站,以及不同的解析方法。这是一个很长的故事。本文主要讲思路。

  1.4 成果展示1.4.1 程序运行效果

  

  1.4.2 爬坡数据展示

  

  2. 使用现有数据进行过滤

  如果你提前下载了所有的新闻文章data,那么这个方法无疑是最方便的,省去了爬取数据的漫长过程,也让你免于对抗反爬机制。

  2.1 数据源

  下载链接:

  以上是一位读者朋友爬取的人民日报新闻数据,包括19年至今的数据。每月更新一次,应该可以满足海量人对数据的需求。

  另外,我还有之前爬过的18年一整年的数据。有需要的朋友可以私聊我。

  2.2 搜索代码

  以下图所示的目录结构为例。

  

  假设我们有一些关键词,需要检查文章这些消息中哪些收录关键词。

  import os

# 这里是你文件的根目录

path = "D:\\Newpaper\\2018"

# 遍历path路径下的所有文件(包括子文件夹下的文件)

def iterFilename(path):

#将os.walk在元素中提取的值,分别放到root(根目录),dirs(目录名),files(文件名)中。

for root, dirs, files in os.walk(path):

for file in files:

# 根目录与文件名组合,形成绝对路径。

yield os.path.join(root,file)

# 检查文件中是否包含关键词,若包含返回True, 若不包含返回False

def checkKeyword(filename, kwList):

with open(filename, "r", encoding="utf-8") as f:

content = f.read()

for kw in kwList:

if kw in content:

return True, kw

return False, ""

if __name__ == "__main__":

# 关键词数组

kwList = ["经济", "贸易"]

#遍历文章

for file in iterFilename(path):

res, kw = checkKeyword(file, kwList)

if res:

# 如果包含关键词,打印文件名和匹配到的关键词

print("文件 ", file," 中包含关键词 ", kw)

  2.3 运行结果

  运行程序从文件中过滤掉收录关键词的文章。

  

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线