admin管理员组文章数量:1593935
目录
- 一、什么是爬虫?
- 二、HTML
- 三、爬虫基本原理
- 四、爬虫三大库
- 1.Request库
- 2. BeautifulSoup库
- 五、正则表达式
- 1. 正则表达式常用符号
- 2.re模块及其方法
一、什么是爬虫?
网络爬虫,其实叫作网络数据采集更容易理解。
就是通过编程向网络服务器请求数据(HTML表单),然后解析HTML,提取出自己想要的数据。
归纳为四大步:
1.根据url获取HTML数据
2.解析HTML,获取目标信息
3.存储数据
4.重复第一步
二、HTML
什么是HTML?
超文本标记语言(英语:HyperTextMarkupLanguage,简称:HTML)是一种用于创建网页的标记语言,里面嵌入了文本、图像等数据,可以被浏览器读取,并渲染成我们看到的网页样子。
所以我们才会从先爬取HTML,再 解析数据,因为数据藏在HTML里
比如这就是一个简单的html程序
<!DOCTYPE html>
<html>
<head>
<title>This is a title</title>
</head>
<body>
<p>Hello world!</p>
</body>
</html>
三、爬虫基本原理
在编写python爬虫程序时,只需要做以下两件事:
①发送GET请求(模拟计算机对服务器发起Request请求),获取HTML
②解析HTML,获取数据
这两件事,python都有相应的库帮你去做,你只需要知道如何去用它们就可以了。
四、爬虫三大库
1.Request库
作用是请求网站获取网页数据
import requests
res = requests.get('http://www.baidu')
print(res) # 返回200则请求网址成功,404或者400则失败
print(res.text)
显示的结果和F 12的一样
有时爬虫需要加入请求头来伪装成浏览器,以便更好地抓取数据。
在F 12里的network里headers中找到User-Agent进行复制
import requests
headers = {
'User-Agent':' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko))Chrome/87.0.4280.66 Safari/537.36'
}
res = requests.get('http://www.baidu')
print(res) # 返回200则请求网址成功,404或者400则失败
print(res.text)
Requsets 库不仅有get()方法,还有post()等方法,用来提交表单来爬取需要登陆才能获取数据的网络。
如果遇到抛出异常,修改后爬虫程序还需要再重新运行,效率很低。这时可以使用try来避免异常
try:
print(res.text)
except ConnectionError #出现except后面的错误后执行下面聚聚
print('拒绝连接')
2. BeautifulSoup库
通过BeautifulSoup库可以轻松解析Request库请求的页面,并把网页的源代码解析成Soup文档,以便过滤提取数据
import requests
from bs4 import BeautifulSoup
headers = {
'User-Agent':' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko))Chrome/87.0.4280.66 Safari/537.36'
}
res = requests.get('http://www.baidu')
soup = BeautifulSoup(res.text,'html.parser') # 对返回的结果进行解析
print (soup.prettify())
其实输出的内容和request的一样,但它按照标准缩进格式的结构输出,为后续数据过滤提取做好准备。
解析Soup文档可以使用find()、find_all()和selector()定位需要的元素。
1.find_all()
soup.find_all( ‘div’,“item” ) ## 查找div标签,class=“item”
soup.find_all( ‘div’,class=“item” )
2.find()
与上者类似,只是find_all()返回的是文档中符合条件的所有tag,是一个集合(class ’ bs4.element.ReaultSet ’ )
而find()是返回一个Tag(class ’ bs4.element.Tag ’ )
五、正则表达式
正则表达式是一个特殊的符号系列,用于检查一个字符串是否与某种模式匹配。
用的是python中的re模块
1. 正则表达式常用符号
2.re模块及其方法
1.search()
用于匹配并提取第一个符合规律的内容,返回一个正则表达式对象。
re.match ( pattern , string , flags=0 )
其中:
pattern为匹配的正则表达式
string为匹配的字符串
flag为标志为,用于控制正则表达式,如是否区别大小写等
下面附上代码
#encoding: utf-8
import requests
import re
import json
import csv
import time
import datetime
# cookie替换成从自己的浏览器获取到的cookie,需要登录后再获取否则无法爬取超过5页数据
cookie = '你自己的cookie'
headers = {
'Host':"xueqiu",
'Referer': 'https://xueqiu/',
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36",
'Accept':"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
'Connection':'keep-alive',
'Cookie': cookie
}
# 初始化数据
page = 1
userid = 9219380043 # 这里填写你要爬取的用户UID
type = 0
url = 'https://xueqiu/v4/statuses/user_timeline.json'+'?page='+str(page)+'&user_id='+str(userid)+'&type='+str(type)
response = requests.get(url, headers = headers)
text = response.text
dict_text = json.loads(text)
# 获取maxPage
maxPage = dict_text['maxPage']
userName = dict_text['statuses'][0]['user']['screen_name']
csv_headers = ['id','user_id','source','title','created_at','retweet_count','reply_count','fav_count','truncated','commentid','retweet_status_id','symbol_id','description','type','source_link','edited_at','mark', 'reward', 'liked', 'quote_cards', 'rqtype', 'paid_mention', 'is_answer', 'donate_count', 'text', 'is_no_archive', 'topic_desc', 'firstImg', 'offer', 'topic_symbol', 'longTextForIOS', 'cover_pic', 'promotion_url', 'target', 'topic_pic_headOrPad', 'retweeted_status', 'like_count', 'commentId', 'status_industry', 'meta_keywords', 'is_column', 'timeBefore', 'is_bonus', 'favorited', 'recommend_cards', 'is_original_declare', 'topic_pic_thumbnail', 'score', 'is_refused', 'reward_amount', 'notice_tag', 'promotion_pic', 'excellent_comments', 'talk_count', 'show_cover_pic', 'expend', 'is_private', 'pic_sizes', 'new_card', 'rqid', 'fragment', 'topic_pic', 'rawTitle', 'stockCorrelation', 'promotion_id', 'canEdit', 'blocking', 'pic', 'blocked', 'topic_title', 'reward_user_count', 'cover_pic_size', 'reward_count', 'forbidden_retweet', 'card', 'topic_pic_thumbnail_small', 'view_count', 'reply_user_count', 'is_ss_multi_pic', 'tagStr', 'common_emotion', 'answers', 'weixin_retweet_count', 'tags', 'favorited_created_at', 'controversial', 'donate_snowcoin', 'mp_not_show_status', 'mark_desc', 'user', 'reply_user_images', 'tagsForWeb', 'order_id', 'current_stock_price', 'forbidden_comment']
last_index = 0
statuses_formatted = []
csv_headers_statuses_formatted = ['发布时间','转发数','评论数','收藏数','点赞数','动态内容']
for page in range(1,maxPage+1):
url = 'https://xueqiu/v4/statuses/user_timeline.json'+'?page='+str(page)+'&user_id='+str(userid)+'&type='+str(type)
response = requests.get(url, headers = headers)
text = response.text
dict_text = json.loads(text)
print('正在爬取第'+str(page)+'页...')
if page == 1:
statuses = dict_text['statuses']
else:
statuses = statuses + dict_text['statuses']
print('当前爬取的数据量:'+str(len(statuses))+'条')
# 格式化created_time, text
for index in range(last_index,len(statuses)):
before_formatting = dict_text['statuses'][index-last_index]['created_at']
if before_formatting:
before_formatting = datetime.datetime.fromtimestamp(int(before_formatting) / 1000).strftime('%Y-%m-%d %H:%M:%S')
dict_text['statuses'][index-last_index]['created_at'] = before_formatting
temp_text = dict_text['statuses'][index-last_index]['text']
if temp_text:
temp_text = re.compile(r'<[^>]+>',re.S).sub('', temp_text)
print(temp_text)
dict_text['statuses'][index-last_index]['text'] = temp_text
if len(dict_text['statuses'][index-last_index]['text']) > 0:
statuses_formatted.append(dict(发布时间=dict_text['statuses'][index-last_index]['created_at'],转发数=dict_text['statuses'][index-last_index]['retweet_count'],评论数=dict_text['statuses'][index-last_index]['reply_count'],收藏数=dict_text['statuses'][index-last_index]['fav_count'],点赞数=dict_text['statuses'][index-last_index]['like_count'],动态内容=dict_text['statuses'][index-last_index]['text']))
last_index = len(statuses)
# 防止反爬虫机制,每爬取100条休息15秒
if page%100 == 99:
time.sleep(15)
# with open(str(userName)+'.csv', 'w', encoding='utf-8', newline='') as fp:
# writer = csv.DictWriter(fp,csv_headers)
# writer.writeheader()
# # writer.writerows(statuses)
with open(str(userName)+'_Formatted.csv', 'w', encoding='utf-8', newline='') as fp:
writer = csv.DictWriter(fp,csv_headers_statuses_formatted)
writer.writeheader()
writer.writerows(statuses_formatted)
让我们看看结果
版权声明:本文标题:雪球网股票用户评论爬虫 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1728182382a1148514.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论