自学经验总结+实战:python爬虫的自我修养与每天微信给女朋友发一份直男日报

news/2024/10/16 2:23:28/

直男日报:

# 记录在一起多少天

# 爬取女朋友所在城市的天气

# 每天给女朋友一句土味情话

# 爬取Bing主页的壁纸,保存到本地并发送

 

自学爬虫一个月左右,先用R后用python,看了许多帖子也走了不少弯路,目前可以实现R和python的静态网页的抓取,RSelenium的动态网页抓取,分享一下自学的经验。

在看别人的文章常常遇到不懂的名词,我的建议是去把那些出现频率高的术语弄懂,如果能加几个python社群就更好了。

譬如你不懂这里的静态网页和动态网页是什么,而这两个又对这篇文章理解有决定性作用,建议先百度之。学爬虫的过程就像盖一个大楼。粗略的打个比方,一开始考虑甲方的要求是什么,根据这个要求琢磨楼怎么盖,画出来模子再研究这么盖地暖怎么铺、中央空调怎么接,接了管道之后这个大楼还稳不稳?这就要考虑水泥的质量和建材。所以爬虫越到后面,你发现自己的焦点已经从技术变成了网页的基础:html协议的结构,为什么html源码需要解析,js脚本的加载,CSS控制网页布局etc

whatever,学习最好的方式是带着问题学,建议遇到这些问题的时候再去百度。

 

先讲一下我学爬虫的足迹,看实例的朋友可跳过这一部分

爬虫能做什么:在批量结构类似的网站上爬取指定信息,如豆瓣top250电影的名称、主演、评分.....

→top250爬虫实例,对着实例学习(个人感觉requests包和bs4包眉清目秀,比较适合上手),贴一段我的代码,只爬了第一页

import requests
from bs4 import BeautifulSoupdef getHTML(url):headers = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}response = requests.get(url, headers=headers, timeout=10)response.raise_for_status()return response.textweb = getHTML("https://movie.douban.com/top250")
soup = BeautifulSoup(web, 'html.parser')
# CSS选择器,得到标签
name = soup.select('.hd a > span:nth-of-type(1)')
for i in range(len(name)):name[i] = name[i].get_text()

→getHTML获得网页源码,那response又是什么呢?请百度:html协议的结构(注意请求头),请求方式(注意get)。改变headers中的’user-agent'是模拟浏览器客户端,如何查自己浏览器的user-agent自行百度。timeout=10是最大请求时间为10s,超过这个时间脚本将不再进行尝试访问。response是服务器的响应,通过属性text获得网页源码,raise_for_status()函数如果访问成功则跳过。

soup = BeautifulSoup(web, 'html.parser')

→对网页源码进行解析,推荐果冻公开课第四课,什么是DOM:https://www.zhihu.com/question/34219998
不同解析器之间速度和兼容性有差别,咱刚入门也不讲究这个,就用了系统自带的html.parser。
为什么爬虫还要对源码进行解析?我的理解是,源码是一堆字符串,解析之后可以建立不同节点之间的联系,让python识别这是html文档,从而可以利用节点之间的树状关系对目标数据进行定位。

# CSS选择器,得到标签
name = soup.select('.hd a span:nth-of-type(1)')

→如何选择目标元素呢?这涉及选择器的问题,一般有xpath和CSS两种选择器,一开始用R的时候上手的是xpath,但select()只支持CSS选择器,这两种选择器在w3school都可以查到,建议学一遍。在这里的意思是:在所有hd的class下的a标签里选择第一个span标签,可见对应的是电影中文标题。

我们查看变量name,是一个list,每个元素是对应的标签

name# Out
[<span class="title">肖申克的救赎</span>,<span class="title">霸王别姬</span>,<span class="title">这个杀手不太冷</span>,<span class="title">阿甘正传</span>,<span class="title">美丽人生</span>,<span class="title">千与千寻</span>,<span class="title">泰坦尼克号</span>,<span class="title">辛德勒的名单</span>,<span class="title">盗梦空间</span>,<span class="title">忠犬八公的故事</span>,<span class="title">机器人总动员</span>,<span class="title">三傻大闹宝莱坞</span>,<span class="title">放牛班的春天</span>,<span class="title">海上钢琴师</span>,<span class="title">楚门的世界</span>,<span class="title">大话西游之大圣娶亲</span>,<span class="title">星际穿越</span>,<span class="title">龙猫</span>,<span class="title">熔炉</span>,<span class="title">教父</span>,<span class="title">无间道</span>,<span class="title">疯狂动物城</span>,<span class="title">当幸福来敲门</span>,<span class="title">怦然心动</span>,<span class="title">触不可及</span>]

然后提取每个标签的文本信息即可,有许多不同的方式,此处使用get_text()

for i in range(len(name)):name[i] = name[i].get_text()

再次查看name

# Out['肖申克的救赎','霸王别姬','这个杀手不太冷','阿甘正传','美丽人生','千与千寻','泰坦尼克号','辛德勒的名单','盗梦空间','忠犬八公的故事','机器人总动员','三傻大闹宝莱坞','放牛班的春天','海上钢琴师','楚门的世界','大话西游之大圣娶亲','星际穿越','龙猫','熔炉','教父','无间道','疯狂动物城','当幸福来敲门','怦然心动','触不可及']

 

如果之前都好好百度的话,看到这里恭喜你静态网站你几乎都可以爬了,注意在这里我们撇开爬虫的效率和反爬虫不谈,上面谈的希望能提供一点帮助给那些想入门爬虫的朋友。

 

下面开始我们正儿八经的实战项目,每天给女朋友发一份直男日报

需要用到的包有

import itchat #对接微信,用python给女票发消息
import datetime #获取当前日期并进行日期的运算
import os #操作路径的包、
from skimage import io #从url读取图片,以数组格式储存
import matplotlib #在这里用来将数组格式的RGB图片保存成png格式
import re #正则表达式模块
import requests #爬虫请求模块
from bs4 import BeautifulSoup #解析html源码

# 记录在一起多少天

def get_datetime():begin_time = datetime.date(2018, 5, 20)now = datetime.date.today()delta = now - begin_timedays = delta.daysreturn days

日期有datetime.date和datetime.datetime两种对象,datetime格式精确到小时分钟秒,date年月日;两个date对象可以做加减运算;得到timedelta对象,它的属性days可返回int格式的天数

 

# 爬取每天的天气

def get_HTML(url):'''获取一个网页,headers模拟浏览器的报头,注意是字典形式和键的名称;raise_for_status()如果没有获取成功会返回连接状态;编码方式用响应的apparent_encoding;在查找资源中我们只需要在网页源码中找即可,所以返回响应的文本'''headers = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) \AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'}response = requests.get(url, headers=headers, timeout=10)response.raise_for_status()response.encoding = response.apparent_encodingreturn response.textdef get_weather(city):'''通过观察网页结构,得到不同天气城市url之间的规律;将html源码解析成DOM树soup,不同的节点开始建立联系;利用CSS选择器找到相应的节点提取出标签,get('href'),get_text()得到文本,注意这两个函数都是标签的函数,不是列表'''url = 'http://www.weather.com.cn/textFC/' + city + '.shtml'web = get_HTML(url)soup = BeautifulSoup(web, 'html.parser')# 这个网站天气分为白天和夜晚。存储在不同的tag下weather_day = soup.select('.conMidtab3 table tr:nth-of-type(1) td:nth-of-type(3)')weather_day = weather_day[0].get_text()weather_night = soup.select('.conMidtab3 table tr:nth-of-type(1) td:nth-of-type(6)')weather_night = weather_night[0].get_text()if weather_day == weather_night:weather = weather_dayelse:weather = weather_day + '转' + weather_night# 同理温度temperature_max = soup.select('.conMidtab3 table tr:nth-of-type(1) td:nth-of-type(5)')temperature_max = temperature_max[0].get_text()temperature_min = soup.select('.conMidtab3 table tr:nth-of-type(1) td:nth-of-type(8)')temperature_min = temperature_min[0].get_text()temperature = temperature_max + '°C' + '/' + temperature_min + '°C'# 得到风力和风速wind_direction = soup.select('.conMidtab3 table tr:nth-of-type(1) td:nth-of-type(4) span:nth-of-type(1)')wind_direction = wind_direction[0].get_text()wind_force = soup.select('.conMidtab3 table tr:nth-of-type(1) td:nth-of-type(4) span:nth-of-type(2)')wind_force = wind_force[0].get_text()wind = {'wind_direction': wind_direction, 'wind_force': wind_force}w = {'weather':weather, 'temperature':temperature, 'wind':wind}return w

 

# 每天一句不同的土味情话,从网上把搜集好的土味情话打包放到txt文件里,为方便代码阅读贴一下

def get_earthyLove(delta):filename = 'earthyLove.txt'with open(filename, 'r') as f:lines = []org_lines = f.readlines()for ln in org_lines:if len(ln) != 1:#去掉\nlines.append(ln)line = lines[delta]return line.split('、')[1]#去掉序号和顿号

将txt文本进行处理:去掉读入列表里的\n;去除序号和顿号;在这里去除顿号的方法使用的是每一行前几位是数字,事实上用split函数以顿号为分隔符能达到同样的效果。

 

#爬取每天的Bing壁纸

有很多写相关的博客但大多对初学者不怎么友好,要么写的很玄学要么就是太讲究,一开始研究了两天正则表达式,终于渡劫爬到了壁纸的url,以为壁纸是动态加载的大赞微软nb,后来大佬告诉我正则表达式能找到的网页源码里肯定也有,我横着看竖着看终于发现url在<head>里,只不过<body>里没有罢了...但还是建议两种方法都掌握一下

def get_jpg(url):html = get_HTML(url)   
# html解析soup = BeautifulSoup(html, 'html.parser')jpg_url = soup.select('#bgLink')[0].get('href') #get()获取标签属性,get_text()获取文本img_url = url + jpg_urlreturn img_url
# =============================================================================
# 正则表达式匹配,网上讲正则的很多,建议廖雪峰老师的正则表达式和菜鸟教程对照着看,然后做一下廖雪峰老师的课后题
#     re_jpg = re.compile(r'url:.{10,90}jpg')
#     jpglist = re.findall(re_jpg, html)
#     if jpglist:
#         jpg_url = jpglist[1].split('/')[1]
#         image_url = url + jpg_url
#         return image_url
#     else:
#         print('failed')
# =============================================================================def get_img():'''这里用到skimage里的io.imread读取来自网页的jpg图片,尝试用pyplot.imread貌似只能读取png格式的文件'''url = 'https://cn.bing.com'img_url = get_jpg(url)img = io.imread(img_url)return img

到这里所有的准备工作就已经完成了,剩下的就是利用itchat发消息了

def send_to_girlfriend(name, city):'''将所有函数打包,修改工作路径到earthy.txt所在路径'''os.chdir('C:\\Users\\mac\\Desktop\\cufe\\self\\program_learning\wxRobot')# 以2018.05.20为第一天,具体的+1和-445与代码逻辑无关,获取各变量datetime = get_datetime() + 1delta = datetime - 445earthyLove = get_earthyLove(delta)w = get_weather(city)weather = w['weather']tem = w['temperature']wind_force = w['wind']['wind_force']wind_direction = w['wind']['wind_direction']# 搭建城市天气url时需要拼音,而在发消息的时候需要用中文,利用字典实现location = {'hongkong':'香港', 'beijing':'北京', 'guangdong':'广州', 'chongqing':'重庆'}city = location[city]# 构建f-string,格式化字符串 msg_org = f'今天是七夕,我是XX给你准备的礼物!'msg_org_datetime= f'你知道嘛,我们已经在一起{datetime}天啦!'msg_datetime = f'我们已经在一起{datetime}天了噢!'if wind_direction == wind_force:#有时候天气网站的风向和风力都一样msg_weather = f'下面是rkun的天气预报:\n今天{city}{weather}\n气温:{tem}\n{wind_direction}'else:msg_weather = f'下面是rkun的天气预报:\n今天{city}{weather}\n气温:{tem}\n{wind_direction}:{wind_force}'msg_earthyLove = f'{earthyLove}'# itchat只能发送本地图片,无法将数组形式的图片发送,故先用matplotlib.image.imsave储存到本地,这个函数的
# 优点在于可以通过定义存储路径的后缀改变图片格式,同时可以将数组形式的图片保存成图像格式wallpaper_index = delta + 20image = get_img()file_path = 'C:\\Users\\mac\\Desktop\\wallpaper\\th(' + str(wallpaper_index) + ').png'matplotlib.image.imsave(file_path, image)# 模拟登陆网页微信,nickName是昵称,remarkName是备注,每次登陆网页微信的每个好友的UserName是随机分配的,
# itchat.send_msg()的第一个参数为目标的Username,这既不是备注也不是昵称,而是每次登陆随机分配的,所以需要先用search_friends找到目标的Usernameitchat.auto_login(hotReload=True)whom = itchat.search_friends(nickName=name)[0]['UserName']if delta == 0:#下面的ifelse语句纯粹是为了让七夕和其他日子发的消息不一样,直接看else就好itchat.send_msg(msg_org, whom)itchat.send_msg(msg_org_datetime, whom)itchat.send_msg(msg_weather, whom)itchat.send_msg(msg_earthyLove, whom)else:itchat.send_msg(msg_datetime, whom) itchat.send_msg(msg_weather, whom)itchat.send_msg(msg_earthyLove, whom)itchat.send_image(file_path, whom)if __name__ == '__main__':#如果所有模块成功importsend_to_girlfriend('J', 'guangdong') 

来一张效果图

 


http://www.ppmy.cn/news/197167.html

相关文章

天问:《三体》世界真的存在吗?(太阳系与银河系简介)

天文入门&#xff1a;太阳系与银河系 ----兼谈《三体》中三星系统的原型 【阅读准备】 建立模型&心算说明&#xff1a; 如果你既非天文专业也非物理专业&#xff08;本人也不是&#xff09;&#xff0c;又是初次看到本文&#xff0c;一定不要被眼花缭乱的天文数据给吓蒙了…

ascii码图片

铁臂阿童木 .be.$$be.#$$$Nc.R$$$$$o.uQ$$$$$$bo..Jod$$$$$$$$$e..dd$$$$$$$$$$$$$$e..d$$$$$$$$$$$$$$$$$bu:W$$$$$$$$$$$$$$P?T*$b:$$$$$$$$$$$$$$#%!!!(#cJ$$$$$$$$****R$#)!!!!!!N :8$$$$$$$#???TT(?!!?XX!!Rr4$9$$$$$RX!!!!!!!!!X…

《增长黑客》节选与笔记

《增长黑客》节选与笔记 自序1.1 创业家的黑暗前传1.2 增长黑客的胜利1.3 什么是“增长黑客”1.4 增长黑客的职责和特质1.5 一切用数据说话1.6 增长黑客担任的团队角色1.7 如何招聘增长黑客1.8 如何成为增长黑客1.9 增长黑客的常用工具箱 第2章 创造正确的产品 2.1 …

《奇特的一生》——致敬时间的神

谁是时间的神&#xff1f; 《星际穿越》说四维时空中“时间就像水一样”被分配&#xff0c;想来时间的神能做到的也不过如此。柳比歇夫作为《奇特的一生》主人公&#xff0c;在这个尺度下就是时间的神&#xff01; 很多人都觉得时间像捧在手上的水慢慢流逝&#xff0c;无法挽…

使用 Python 设置高斯模糊背景

源码 import osimport json import time from lxml import etree import random import requests import win32api import win32con import win32guifrom PIL import Image, ImageFilter from pystray import Icon as icon, Menu as menu, MenuItem as itemSOURCE_PATH D:/pr…

Android Live Wallpaper动态壁纸开发

Live Wallpaper动态壁纸开发 http://www.eoeandroid.com/forum.php?modviewthread&tid69161&fromuid511991 变形金刚动态壁纸源码 http://www.eoeandroid.com/forum.php?modviewthread&tid173128&fromuid511991 国外一个经典的动态壁纸项目源码及讲解 http…

vim键位图

在初学vim的时候&#xff0c;面对众多的命令&#xff0c;不知道该如何记忆&#xff0c;博主便想出在电脑屏幕上记录vim键位的屏保来方便记忆。起初在网上寻找了很久都没有高清的资源&#xff0c;于是自己仿照网上流行版本制作了下面vim键位屏保。 此屏保可以帮助你方便查看命令…

夜光带你走走进全栈式web开发(12)擅长领域

夜光序言&#xff1a; 我真想躲在梦里和暗夜的深处&#xff0c;一遍一遍地吟唱你喜欢的那首好听的歌曲&#xff0c;忧伤而不哀怨&#xff0c;你若愿听&#xff0c;我一歌再歌&#xff0c;以至于我泪水盈眶。你若腻了&#xff0c;我就赊一杯清愁酩酊&#xff0c;一醉再醉。这是我…