今日头条文章采集软件(爬取思路:请求Ajax数据获取文章url请求文章(组图) )
优采云 发布时间: 2022-01-10 01:13今日头条文章采集软件(爬取思路:请求Ajax数据获取文章url请求文章(组图)
)
1.爬取分析
我们先打开今日头条,搜索“罗志祥”
打开浏览器的开发者工具,红框是我们请求的数据
将搜索界面的滚动条滑动到底部,可以在开发者工具中看到所有请求的数据,加上上一条,一共有7条数据。同时还发现每条数据的offset偏移量是20,所以我们只需要在构造链接请求数据时改变偏移量即可。
点击第一条数据,可以看到请求链接的格式。稍后,我们需要构造参数来生成链接。
为了保证爬虫的稳定性(爬取过程中可能会有验证码),我们需要在请求头中添加如下参数。
现在点击第一条数据,可以看到数据中收录了每个文章的一些数据信息,我们要提取收录文章链接的item_url。
但是我们可以看到,上图中的文章链接并不是今日头条网站,而是今日头条转载的其他网站的文章,以及不同的网站结构@>也不一样,不好解析,所以这里只爬取今天头条网站中的文章。
打开 文章 链接以查看 文章 的内容。
查看网页的源码,可以看到网页是用js渲染的。我们直接使用正则表达式匹配来提取文章的内容。
爬取思路:
请求ajax数据获取文章url请求文章网页正则提取文章主体内容保存文章数据循环爬取2.代码实现
(1) 导入包,构造请求头
import os
import re
import csv
import time
import html
import requests
from urllib.parse import urlencode
headers = {
'cookie': 'tt_webid=6803226732523800077; WEATHER_CITY=%E5%8C%97%E4%BA%AC; tt_webid=6803226732523800077; csrftoken=001*敏*感*词*6806*敏*感*词*ddb1c2b0ef69c22890fcf; ttcid=8b695caa90e6433593bc380c6169f17d27; SLARDAR_WEB_ID=5d5ed608-2dda-4d11-b7ed-238121ba5d44; s_v_web_id=verify_k9gguslb_rEU3y1j3_1Egi_4MUX_BRpa_ppngg9dAp1Op; __tasessionId=gjkq6pqc01587870093173; tt_scid=FiyB9z79VVOWXzxX3rQkVUFrbT.kY47exuDy8fdctQueSFw42.wM3KgKWTxahUmG56f2',
'referer': 'https://www.toutiao.com/search/?keyword=%E7%BD%97%E5%BF%97%E7%A5%A5',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'x-requested-with': 'XMLHttpRequest'
}
(2)请求一条Ajax数据
def get_one_page(offset):
params = {
'aid': '24',
'app_name': 'web_search',
'offset': offset,
'format': 'json',
'keyword': '罗志祥',
'autoload': 'true',
'count': 20,
'en_qc': 1,
'cur_tab': 1,
'from': 'search_tab',
'pd': 'synthesis',
'timestamp': int(time.time())
}
url = 'https://www.toutiao.com/api/search/content/?' + urlencode(params)
try:
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.json()
except requests.ConnectionError:
return None
(3)获取 文章 链接
def get_article_url(json):
if json['count'] != 0: #请求的文章数据不为0
for item in json['data']: #遍历每条文章
if 'article_url' in item: #如果存在文章链接
title = item['title'] #文章标题
publish_time = item['publish_time'] #发布时间戳
datetime = item['datetime'] #发布日期
abstract = item['abstract'] #摘要
article_url = item['article_url'] #文章链接
yield{
'title': title,
'publish_time': publish_time,
'datetime': datetime,
'abstract': abstract,
'article_url': article_url
}
(4)解析文章
def parse_article(article_url):
response = requests.get(article_url, headers=headers) #请求文章
if response.status_code == 200: #响应正常
try:
data = response.content.decode('utf-8')
text = re.findall(r"content:(.+)", data)[0] #正则匹配
text = html.unescape(text) #html转义
text = re.findall(r"'(.+)'", text)[0]
except:
text = None
if text: #替换无效字符
replace_list = [r'\\u003C', r'\\u003E', r'\\u002F', r'p', r'strong', r'p', r'br', r'div (.*?)div']
for replace in replace_list:
text = re.sub(replace, '', text)
return text
(5)保存文章内容
def save_article(content, text):
if not os.path.exists('articles/'):
os.mkdir('articles/')
file_path = 'articles/{0}.{1}'.format(content['title'], 'txt')
if not os.path.exists(file_path): #txt
with open(file_path, 'w', encoding='utf-8') as f:
f.write(text)
with open('articles/articles_table.csv', 'a', encoding='utf-8', newline='') as f:
w = csv.writer(f) #csv
w.writerow([content['title'],content['publish_time'],content['datetime'],content['abstract'],content['article_url'],text])
(6)主函数
def main(offset):
json = get_one_page(offset)
for item in get_article_url(json):
try:
article_url = item['article_url']
text = parse_article(article_url)
if text:
save_article(item, text)
except FileExistsError and OSError:
continue
(7)运行
if __name__ == '__main__':
for i in range(0,7):
main(i * 20)
print('爬取完成')
(8) 爬取结果
3.制作文字云图
分析一下文章主要在说什么。
import csv
import matplotlib.pyplot as plt
import jieba
from wordcloud import WordCloud
#1.读出
text = ''
csv_file = csv.reader(open('articles/articles_table.csv',encoding='utf-8'))
for row in csv_file:
text = text + row[-1]
#2.剪开
cut_text = jieba.cut(text)
stopwords = {'可以','已经','这些','虽然','如果','img','class','handler',
'不是','怎么','甚至','时候','没有','什么','大家','自己'}
cuttext = [i for i in cut_text if i not in stopwords]
#3.以空格拼接起来
result = " ".join(cuttext)
#生成词云
wc = WordCloud(
font_path='C:/Windows/fonts/simhei.ttf', #字体路径
background_color='white', #背景颜色
width=1000,
height=600,
max_font_size=50, #字体大小
min_font_size=10,
mask=plt.imread('bg.jpg'), #背景图片
max_words=1000
)
wc.generate(result)
wc.to_file('wordcloud.png') #图片保存