【写在文章前面:】
为什么会 讨论想到写博客呢?明明自己才学Python半年,很多知识也没有形成系统化的体系,甚至代码规范都没学习过 ,那为什么我还 是 选择开个微信公众号,并且敢于写文章?
原因一:想给自己的青春留下值得回忆的东西。其实自己一直都有记笔记的习惯,无论以前在 学校的时候,还是工作的这几年。遇到不会的或者大神的一些观点,都喜欢在网上写写记记。回想工作的这几年 ,在公司的内网写了有100+的博客(多数是和业务相关,没有推广性)。但是万一我离开了现在的公司,那些能证明我曾经的事情、曾经在键盘上敲下的字符,都将无法回望审视。因此我选择了微信公众号这样的平台。
原因二:向大神看齐,不断提升自己。最近看到一位Python大神(他的公众号是 “清风Python”),写了很多精彩的帖子,比如本篇也是 有感于大神写的Python爬取BOSS直聘网站的帖子,手痒和强烈的兴趣写了以下代码。想来今年3月之前,只听说过 python;想来 2年前,我还和当时的主管说,我不想写代码。现在想想,是 Python和一些过往改变了当时幼稚的想法。从零开始学习python过程中,不得不说,python是真的好玩,而爬虫更甚。人们常说,人没有梦想,和咸鱼有什么区别?我觉得吧,之所以和咸鱼不同,不是因为有梦想,而是因为为 了梦想实现的过程中各种学习和进步。我并没有大的梦想,但是我喜欢学习新 事物过程中的烦躁及解决问题后的成就感。
好像说的有点多了,下面 开始正文。
【目的】
写个小程序,可以直接获取杭州天气
【示例代码】
# coding=utf-8
# @Auther : "鹏哥贼优秀"
# @Date : 2019/7/28
# @Software : PyCharm
import random
from bs4 import BeautifulSoup
import requests
import time
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
def getheaders():
user_list = [
"Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16",
"Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14",
"Mozilla/5.0 (Windows NT 6.0; rv:2.0) Gecko/20100101 Firefox/4.0 Opera 12.14",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0) Opera 12.14",
"Opera/12.80 (Windows NT 5.1; U; en) Presto/2.10.289 Version/12.02",
"Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00",
"Opera/9.80 (Windows NT 5.1; U; zh-sg) Presto/2.9.181 Version/12.00",
"Opera/12.0(Windows NT 5.2;U;en)Presto/22.9.168 Version/12.00",
"Opera/12.0(Windows NT 5.1;U;en)Presto/22.9.168 Version/12.00",
"Mozilla/5.0 (Windows NT 5.1) Gecko/20100101 Firefox/14.0 Opera/12.0",
"Opera/9.80 (Windows NT 6.1; WOW64; U; pt) Presto/2.10.229 Version/11.62",
"Opera/9.80 (Windows NT 6.0; U; pl) Presto/2.10.229 Version/11.62",
"Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
"Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; de) Presto/2.9.168 Version/11.52",
"Opera/9.80 (Windows NT 5.1; U; en) Presto/2.9.168 Version/11.51",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; de) Opera 11.51",
"Opera/9.80 (X11; Linux x86_64; U; fr) Presto/2.9.168 Version/11.50",
"Opera/9.80 (X11; Linux i686; U; hu) Presto/2.9.168 Version/11.50",
"Opera/9.80 (X11; Linux i686; U; ru) Presto/2.8.131 Version/11.11",
"Opera/9.80 (X11; Linux i686; U; es-ES) Presto/2.8.131 Version/11.11",
"Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/5.0 Opera 11.11",
"Opera/9.80 (X11; Linux x86_64; U; bg) Presto/2.8.131 Version/11.10",
"Opera/9.80 (Windows NT 6.0; U; en) Presto/2.8.99 Version/11.10",
"Opera/9.80 (Windows NT 5.1; U; zh-tw) Presto/2.8.131 Version/11.10",
"Opera/9.80 (Windows NT 6.1; Opera Tablet/15165; U; en) Presto/2.8.149 Version/11.1",
"Opera/9.80 (X11; Linux x86_64; U; Ubuntu/10.10 (maverick); pl) Presto/2.7.62 Version/11.01",
"Opera/9.80 (X11; Linux i686; U; ja) Presto/2.7.62 Version/11.01",
"Opera/9.80 (X11; Linux i686; U; fr) Presto/2.7.62 Version/11.01",
"Opera/9.80 (Windows NT 6.1; U; zh-tw) Presto/2.7.62 Version/11.01",
"Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.7.62 Version/11.01",
"Opera/9.80 (Windows NT 6.1; U; sv) Presto/2.7.62 Version/11.01",
"Opera/9.80 (Windows NT 6.1; U; en-US) Presto/2.7.62 Version/11.01",
"Opera/9.80 (Windows NT 6.1; U; cs) Presto/2.7.62 Version/11.01",
"Opera/9.80 (Windows NT 6.0; U; pl) Presto/2.7.62 Version/11.01",
"Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.7.62 Version/11.01",
"Opera/9.80 (Windows NT 5.1; U;) Presto/2.7.62 Version/11.01",
"Opera/9.80 (Windows NT 5.1; U; cs) Presto/2.7.62 Version/11.01",
"Mozilla/5.0 (Windows NT 6.1; U; nl; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.01",
"Mozilla/5.0 (Windows NT 6.1; U; de; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.01",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; de) Opera 11.01",
"Opera/9.80 (X11; Linux x86_64; U; pl) Presto/2.7.62 Version/11.00",
"Opera/9.80 (X11; Linux i686; U; it) Presto/2.7.62 Version/11.00",
"Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.6.37 Version/11.00",
"Opera/9.80 (Windows NT 6.1; U; pl) Presto/2.7.62 Version/11.00",
"Opera/9.80 (Windows NT 6.1; U; ko) Presto/2.7.62 Version/11.00",
"Opera/9.80 (Windows NT 6.1; U; fi) Presto/2.7.62 Version/11.00",
"Opera/9.80 (Windows NT 6.1; U; en-GB) Presto/2.7.62 Version/11.00",
"Opera/9.80 (Windows NT 6.1 x64; U; en) Presto/2.7.62 Version/11.00",
"Opera/9.80 (Windows NT 6.0; U; en) Presto/2.7.39 Version/11.00"
]
user_agent = random.choice(user_list)
headers = {'User-Agent': user_agent}
return headers
def weather():
url = "http://www.weather.com.cn/weather/101210101.shtml"
headers = getheaders()
r = requests.get(url, headers=headers)
r.encoding = 'utf-8'
soup = BeautifulSoup(r.text, "lxml")
lines = soup.find('li', class_="sky skyid lv2 on")
date = lines.h1.get_text()
weather = lines.p.string
low_temp = lines.find('p', class_="tem").i.get_text()
if not lines.find('p', class_="tem").span:
high_temp = "未知"
else:
high_temp = lines.find('p', class_="tem").span.get_text()
temp = high_temp + '-' + low_temp
wind = lines.find('span', class_="S").get('title')
windnumber = lines.find('p', class_="win").i.get_text()
result = {
"日期": date,
"天气": weather,
"温度": temp,
"风向": wind,
"风级": windnumber
}
print(u"日期:{0} \n天气:{1} \n温度:{2} \n风向:{3} \n风级:{4}").format(date, weather, temp, wind, windnumber)
return result
if __name__ == "__main__":
weather()
time.sleep(5)
【效果如下】:
【知识点】
python爬虫,其实就是模拟http请求,然后通过解析界面响应,从中得到自己想要的东西。听上去感觉很高大上,其实从代码实现上,还是蛮简单的。下面大致说下,以上示例代码。
1、模拟http请求,关键就是 以下代码 。通过调用request方法,将请求头和具体网站的URL加进去,就会生成对应的界面响应r。这 就有点像烧菜,只要放进菜和调料,一出锅就是可以吃的菜了。
里面唯一有点意思的就是请求头 的模拟构造。本代码参考了大神的请求方法,通过随机获取一个请求头 的方式实现。其实还 可 以调用fake_useragent库来 构造虚拟的请求头,但本人偷懒,还没尝试过。
这里为什么要加请求头,原因就是如果不加的话,访问的网站可能会认为你就是个程序(我还真的是个程序)在访问,因此会通过同一时间内的访问次数来 限制你的IP,比如多少时间 内不允许再访问,名为反爬虫。那通过模拟请求头的方式就是反反爬虫,有点无间道的意思。
2、我今天要记录的是还是BeautifulSoup方法,也就是对响应的解析,得到我们想要的内容。示例代码 中Lines获取的响应内容就是下图
因此针对这段 代码 的解析就很简单 理解了。由于我对html还 不了解,所以无法用正确的术语进行解释,就这样看看吧。
lines.p : 获取第一个p标签,即<p class="wea" title="多云转晴">多云转晴</p>;lines.a/lines.li等都是一样的道理;
lines.p.string,获取第一个p标签的内容,即“多云转晴”;当然也可以 用lines.p.get_text(),两个方法是一样的;
lines.find('p', class_="tem"):获取第一个p,并且class="tem"的标签;如果要查找所有一样的标签,那就要用find_all。注意,这里不是findall,findall是 用于re库中的 正则表达式查找。
lines.find('span', class_="S").get('title'):就是获取<span class="S" title="南风"></span>中的title内容,即“南风”;
其实如果不 调用BeautifulSoup方法的话,也可以用正则表达式实现,但是 肯定没这么方便。
【备注】:
(1)如果通过soup.p.string获取的结果无法进行字典操作,报“TypeError: string indices must be integers, not str”
解决方法:通过json.loads(XX)来将结果转换成json格式,就可以进行字典操作了。
3、最后是通过pyinstller库,将上述示例代码生成一个exe的可执行程序,这样就不依赖于python了,命令也很简单:pyinstaller -F XXX.py即可。
【结尾】:
第一次在公众号写文章,虽是记录自己的成长,但是如果对其他看客有所帮助,那就也算是我值得开心的一件事了。
【参考】:
1、如何爬取BOSS直聘网站的招聘信息:
https://blog.csdn.net/SlaughterDevil/article/details/95797767
2、BeautifulSoup方法的简介:
https://blog.csdn.net/qq_21933615/article/details/81171951
【自我推荐】
如果大家觉得有所帮助或者想一起学习,可以关注我的公众号“鹏哥贼优秀”,谢谢大家!