python版本:python3.7
编译器:pycharm
所爬取的网址:http://www.weather.com.cn/weather/101020100.shtml (中国天气网上海)
所用方法:lxml的css选择器
lxml的具体使用方法可以参照我另一篇博客:https://blog.csdn.net/qq_38929220/article/details/83623057
最后运行结果示例如图:
爬取思路
- 检查网站的robots.txt文件
- 查看网页源代码找到所要爬取的内容
- 写表达式爬取想要的内容
- 写入csv文件
检查网站的robots.txt文件
robots.txt文件定义了对爬虫的限制,可以直接手动在想要爬的网址后输入robots.txt查看
例:http://www.weather.com.cn/robots.txt
也可以通过代码实现,这样在爬取其他网页时也可以复用,爬多网页时比较方便。
# 检查url传递的robots.txt限制
if rp.can_fetch(user_agent, url):
throttle.wait(url)#延迟函数
html = download(url, headers, proxy=proxy, num_retries=num_retries)
查看网页源代码找到所要爬取的内容并爬取
右键网页点击查看网页源代码就可以看到网页的源代码。
找出想爬取信息对应的代码。
可以看出此网站的天气有wea、tem、win三个属性,均写在p标签里,没有定义父标签,可单独直接抓取。
td = tree.cssselect('p.wea,p.tem,p.win')
for wea in td:
#strip方法用于移除字符串头尾指定的字符
print(wea.text_content().strip('\n'))
写入csv文件
import csv
from urllib.parse import urlparse
import lxml.html
from link_crawler import link_crawler
import json
#使用回调类而非回调函数以保持csv中write属性的状态
class ScrapeCallback:
def __init__(self):
#不写newline=''的话会出现空行
self.writer = csv.writer(open('weather.csv', 'w',newline=''))
#天气 最高温/最低温 风力
self.fields = ('天气','最高/低温','风力')
self.writer.writerow(self.fields)
def __call__(self, url, html):
tree = lxml.html.fromstring(html)
td=tree.cssselect('p.wea')
n=0
for wea in td:
row=[]
row.append(tree.cssselect('p.wea')[n].text_content().strip('\n'))
row.append(tree.cssselect('p.tem')[n].text_content