python是使用的最频繁的,也是最好用的爬虫工具。
使用python抓取天气,首先要引入一些模块,用来辅助抓取程序。
from bs4 import BeautifulSoup
import requests
from requests.exceptions import ReadTimeout,ConnectionError,RequestException
import re
import time
import MySQLdb
引入模块说明:
BeautifulSoup:解析、遍历、维护“标签树”,爬虫程序使用的最频繁的就是他了。
requests:简单易用的HTTP库,里面有一些异常捕获,比如超时、连接错误、获取异常等。
re:正则表达式。
time:获取时间的模块;
MySQLdb:与数据库打交道。
进入正题
定义header,让抓取程序伪装为浏览器,避免被抓取网站屏蔽:
headers = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"}
正式代码:
# -*- coding: utf8 -*-
from bs4 import BeautifulSoup
import requests
from requests.exceptions import ReadTimeout,ConnectionError,RequestException
import re
import time
import MySQLdb
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
headers = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"}
# 获取郑州周边市县天气信息
def nearbyWeather():
weatherInfo = []
status = True
while status:
try:
res = requests.get("https://www.tianqi.com/jiayuguan/", headers=headers, timeout=30)
# 设置页面编码格式
res.encoding = "utf-8"
if res.status_code == 200:
soup = BeautifulSoup(res.text, "html.parser")
status = False
else :
status = True
except ReadTimeout:
status = True
print(u"Exception:超时……")
except ConnectionError:
status = True
print(u"Exception:连接错误……")
except RequestException:
status = True
print(u"Exception:请求异常……")
except BaseException, e:
status = True
print e.message
nearbyWeather = soup.select(".raweather760")[1].select("li")
for nearby in nearbyWeather:
nearbyA = nearby.select("a")
if len(nearbyA) == 2:
aAttrs = nearbyA[0].attrs
pinyin = re.compile("[a-z]+").findall(aAttrs['href'])[0]
weather = aAttrs['title'].replace(u"天气预报:", " ").split(" ")
# 气温
weatherInfo.append(weather[2])
# 天气
weatherInfo.append(weather[1])
#中文
weatherInfo.append(weather[0])
# 拼音
weatherInfo.append(pinyin)
sql = "insert into nearby_weather(temperature, weather, cnName, enName, time) values(%s,%s,%s,%s,%s)"
conn = MySQLdb.connect(host="127.0.0.1", user="root", passwd="root", db="weather", charset="utf8")
cursor = conn.cursor()
for i in range(0, 48, 4):
cursor.execute(sql, (weatherInfo[i], weatherInfo[i + 1], weatherInfo[i + 2], weatherInfo[i + 3], time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))))
conn.commit()
cursor.close()
conn.close()
if __name__ == "__main__":
nearbyWeather()
代码解析:
在代码中,有异常捕获处理,有正则表达式,有字符串拆分等。
在数据处理入库部分,使用批处理,由于数据量很少,只在最后做了提交操作。如果数据量很大,可以一百条判断提交一次。
我这种获取天气的方式,使用了标签属性,通过分析标签属性内容获取具体天气数据。其实还可以通过具体的内部标签获取天气信息,只是这种方式会更复杂一点。