我相信有相当大部分人,学习python最初动机,就是做一个网络爬虫,虽然python的主要强项是数据分析方面(至少我是这样认为的),但这并不妨碍它成为目前最主流的网络爬虫编写语言。

网络爬虫是什么?

——网络上一切看得见的,或看不见的数据,无论是用浏览器还是App或是其他工具打开的,只要是数据,理论上都是通过“数据包”的形式在网络上传播的,爬虫就是用一堆代码,去获取那些数据包,然后把它们解析成我们能看得懂的样子。

好像比较拗口……,再用大白话说一次:爬虫,就是数据获取工具。而且,出于各种原因,大家最好在正式场合不要说“爬虫技术”,而要说“数据获取技术”。

正式开始,先介绍一下python在数据获取方面,我常用的包有哪些:

  • requests  用于获取页面的原始代码

  • lxml(etree)  用于对网页标签进行定位,可以解析出需要的数据

  • bs4(BeautifulSoup)  同上,最早的爬虫包,现在用的少了,但在某些场景还是有它的用处

  • selenium(webdriver)  模拟浏览器,应付比较多渲染效果、有用户登录或验证码的场景

在掌握了常用的包之后,数据获取的大致流程如下(以获取网站数据举例):

  • 首先了解自己需要的数据是哪些,百度一下这些数据大概都在哪些网站上有,迅速人工浏览一下这些目标网站的首页和内页情况,观察一下页面的复杂程度、是否有大量渲染效果、是否有用户登录、是否需要验证码……等等,然后确定一个最终的目标网站,要求是在拥有我们需要的数据的前提下,数据获取难度相对较小。

  • 用requests(或webdriver)把页面获取下来(如果有渲染、用户登录或验证码,就需要使用相应工具处理后才能获取到),对目标网站的网页代码进行分析,定位出我们需要的数据,并把这些数据用dict类型或list类型组织起来,形成对我们有用的数据包。

  • 把组织好的数据,存到mongoDB或excle、txt文件里面去,方便我们使用。

做完这些,爬虫基本上就做完了。通常一个爬虫代码,只能用于一个网站,我们通常称负责页面解析的代码为“爬虫模板”。网站页面的代码如果发生更新,会导致爬虫模板不能获取到正确的数据,甚至直接报错,需要对爬虫模板进行相应的更新。对于需要持续获取数据的爬虫,这个“博弈”过程会反复出现。

循例,我们还是上一个例子,来简单介绍一下上面的流程:

第一步  确定需求、确定目标网站:

比如,我们需要历史上广州的天气情况数据,我们先百度一下“全国天气历史数据”,我们大概可以找到以下这些网站:

中国天气网:http://www.weather.com.cn/forecast/

IP138天气查询:https://qq.ip138.com/weather/history.htm

天气后报网:http://www.tianqihoubao.com/

……

经过对每个网站进行一些简单的点击,翻看,感觉天气后报网比较适合爬取,就把它确定为目标网站吧。

第二步  直接上代码:

刚开始,我们应该是不知道这个网站是否有什么防爬技术,先用最简单的方法去试试,看能不能work得了

import requestsurl = 'http://www.tianqihoubao.com/lishi/guangzhou/month/201904.html'rs = requests.get(url=url)urlText = rs.textprint(urlText)

怀着忐忑的心情运行之,发现输出是这样的:

OK,it works,可以进行下一步工作了(如果没出现这种网页源码,就要尝试一下模拟浏览器了)。

接下来,我们进行页面分析,当我们在浏览器地址栏中输入url地址:

http://www.tianqihoubao.com/lishi/guangzhou.html时,出现以下页面

历史上每个月,是这个页面上的一个链接,如果要获取全部的历史天气记录,我们需要先把这个页面上所有的历史天气链接地址,获取下来,存到一个list类型的变量中。

然后,我们点击某一个月的链接,看看内页的情况,出现以下页面

这就是我们要获取的数据了。

在这个页面上,我们按F12(谷歌浏览器),弹出开发者工具,在Elements栏目下,点最左上角的那个小箭头,然后把鼠标移到页面上我们要获取的任意一个数据上面,像这样

这时,开发者工具的Elements窗口中的内容,就会定位到这个数据元素在页面源代码中的位置,类似这样

我们发现,这个页面是用table+tr+td的模式排放数据的(这个办法比较老土,居然这个网站还在用O(∩_∩)O),接下来,就可以编写爬虫了。

先去拿每个月的url地址,代码如下:

import requestsfrom lxml import etreeclass My_Spider:    def __init__(self):        self.base_url = 'http://www.tianqihoubao.com'        self.month_home = 'http://www.tianqihoubao.com/lishi/guangzhou.html'    def get_month_list(self):        rs = requests.get(url=self.month_home)        listUrlText = rs.text        listUrlTextEtree = etree.HTML(listUrlText)        month_list = listUrlTextEtree.xpath("//div[@class='wdetail']/div[@class='box pcity']/ul/li/a/@href")        return month_list    def get_weather(self):        month_list = self.get_month_list()        for mon in month_list:            month_url = self.base_url + mon            print(month_url)if __name__ == '__main__':    my_spider = My_Spider()    my_spider.get_weather()

打印结果如下:

你会发现这些地址有长有短,原因是那些短一些的地址中间少了‘/lishi/’。这种问题,在一些老式的网站上经常出现,要解决它。

完整代码(带详细注释):

# coding:utf-8import requestsfrom lxml import etreeimport pandas as pdclass My_Spider:    '''    定义一个类的初始化函数,在函数中定义两个属性,    1、目标网站的地址,这个在后面有用    2、目标城市的每月天气的地址列表    '''    def __init__(self):        self.base_url = 'http://www.tianqihoubao.com'        self.month_home = 'http://www.tianqihoubao.com/lishi/guangzhou.html'    '''    定义一个获取目标城市每月天气的地址列表的函数,    返回值是一个list类型的变量,里面是url地址列表(url不完整,将在后面补全)    '''    def get_month_list(self):        rs = requests.get(url=self.month_home)  # 访问url        listUrlText = rs.text  # 将获得的数据包变成文本形式的网页源码        listUrlTextEtree = etree.HTML(listUrlText)  # 将网页源码文本转换成树形结构,方便xpath定位元素        month_list = listUrlTextEtree.xpath("//div[@class='wdetail']/div[@class='box pcity']/ul/li/a/@href")        print(month_list)        return month_list    '''    进入每日天气列表,并获取每日天气情况    '''    def get_weather(self):        month_list = self.get_month_list()        b_str = '/lishi/'  # 我们发现获得的地址有些缺少这个字符串        weather_group = []        for mon in month_list:            month_url = self.base_url + mon  # 组合好url地址            # 将不完整的url地址补全            if b_str not in month_url:                month_url = self.base_url + b_str + mon            print(month_url)            rs = requests.get(url=month_url)  # 访问url            listUrlText = rs.text  # 将获得的数据包变成文本形式的网页源码            listUrlTextEtree = etree.HTML(listUrlText)  # 将网页源码文本转换成树形结构,方便xpath定位元素            data_body = listUrlTextEtree.xpath("//table/tr")  # 获取需要的大的数据区域            for d_body in data_body[1:]:  # 去掉第一行表头                item = {}                # 获取每一行、每一格数据,组成dict数据包                item['日期'] = d_body.xpath("./td[1]/a/text()")[0].strip().replace('\r\n', '').replace(' ', '')                item['天气状况'] = d_body.xpath("./td[2]/text()")[0].strip().replace('\r\n', '').replace(' ', '')                item['温度'] = d_body.xpath("./td[3]/text()")[0].strip().replace('\r\n', '').replace(' ', '')                item['风力风向'] = d_body.xpath("./td[4]/text()")[0].strip().replace('\r\n', '').replace(' ', '')                print(item)                weather_group.append(item)  # 将数据包放进list类型的变量中        weather_DF = pd.DataFrame(weather_group)  # 将获取到的数据,转成数据表        weather_DF.to_csv('广州历史天气.csv', encoding='utf-8-sig')  # 数据持久化,即把数据表存成csv文件if __name__ == '__main__':    my_spider = My_Spider()    my_spider.get_weather()

在爬取过程中,在控制台监控程序运行情况,工作正常:

最后,我们存下来的CSV文件打开看一下,确保数据存储完成。

——  分割线  ——

当然,这是一个比较简单的爬虫,没有复杂的反防爬技术,但制作一个爬虫的基本流程都有了,复杂爬虫只是在每一步上都需要多付出一些劳动而已。

打完收工!看官可满意否?

爬虫获取不到网页完整源码_你的第一只网络爬虫相关推荐

  1. 使用Python获取数字货币价格(附完整源码)

    使用Python获取数字货币价格(附完整源码) 如果你想要及时了解到加密货币的价格变化,你可以使用Python获取数字货币的实时价格.本文将介绍如何使用Python和CoinGecko API获取数字 ...

  2. 【网络爬虫入门01】应用Requests和BeautifulSoup联手打造的第一条网络爬虫

    [网络爬虫入门01]应用Requests和BeautifulSoup联手打造的第一条网络爬虫 广东职业技术学院 欧浩源 2017-10-14  1.引言 在数据量爆发式增长的大数据时代,网络与用户的沟 ...

  3. halcon车牌识别完整源码_基于chineseocr_lite的身份证、火车票、车牌等中文OCR文字识别...

    简介 chineseocr_lite 超轻量级中文ocr,支持竖排文字识别, 支持ncnn推理 , psenet(8.5M) + crnn(6.3M) + anglenet(1.5M) 总模型仅17M ...

  4. 火牛协议php网页版源码_阿狸子PHP商品订单系统V2.9豪华版源码(竞价单页源码,分销商城)...

    阿狸子PHP商品订单系统V2.9豪华版源码(竞价单页源码,分销商城),非常不错,喜欢的朋友快来下载吧! 环境说明 1.PHP5.3-5.6版本,不支持PHP7 2.mysql5.1及以上 3.PHP须 ...

  5. python:获取加密货币价格(附完整源码)

    python:获取加密货币价格 import ccxt def getprice(symbol, exchange_id):symbol = symbol.upper() # BTC/USDT, LT ...

  6. 【QT学习】扫描二维码获取登录验证码(完整源码)

  7. 电商客源采集源码_福利!送你一个爬虫批量采集阿里巴巴商品数据

    本文主要介绍如何免费采集阿里巴巴批发网商品的批发价格.发货时间.是否代发等信息. 采集字段: 商品标题.商品链接.图片链接.标签1.标签2.标签3.价格.30天成交数. 评价.店铺 功能点目录: 采集 ...

  8. 爬虫之js加密参数破解练习-百度指数爬虫(附完整源码)

    百度指数爬虫 前言 分析 查看响应体 找到加密的代码块 python实现解密过程 完整代码 前言 完整源码如因环境问题无法运行(没有安装node环境),将解密部分换成python(已在博客中附上)即可 ...

  9. 网页爬虫python代码_《用python写网络爬虫》完整版+源码

    原标题:<用python写网络爬虫>完整版+源码 <用python写网络爬虫>完整版+附书源码 本书讲解了如何使用Python来编写网络爬虫程序,内容包括网络爬虫简介,从页面中 ...

最新文章

  1. 想“看见”高性能计算嘛?戳这里开始
  2. oracle雾化试图_Oracle创建物化视图
  3. linux 进程调度类型 总结,Linux进程模型总结
  4. c语言不同类型指针间的强转,C语言中不同的结构体类型的指针间的强制转换详解...
  5. 计算机内存比外存容量大吗,内存容量一般比外存容量大吗
  6. vmclone 问题
  7. html5动态切换class,uni-app v-for循环遍历 动态切换class、动态切换style
  8. android网络配置
  9. 如何在ADO中使用数据读取器(DataReader)读取数据
  10. 计算机在教育中的应用利与弊,多媒体教学的利与弊
  11. 教务管理系统:成绩、课表查询接口设计及抢课、监控功能实现
  12. golang使用xlsx操纵excel浅析
  13. lua入门之二table
  14. echars、象棋、飞机大战、五子棋
  15. CTF 内涵的软件 stage1
  16. 动圈耳机振膜_耳机必看!谈动圈式耳机振膜技术
  17. Redis远程连接不上解决办法
  18. Dex文件格式扫描器:特征API的检测和扫描(小工具一枚)
  19. 【MAC工具】各个Xcode版本对应macOS的版本下载
  20. 一本通 1287:最低通行费 C++

热门文章

  1. 【Kafka】Flink kafka 报错 Failed to send data to Kafka: Failed to allocate memory within the config
  2. 【Mac】Mac iTerm2 使用笔记 远程连接
  3. redis相对于mysql有什么劣势
  4. seafile私有网盘搭建
  5. rsyslog 日志管理服务
  6. 优雅的实现对外接口,要注意哪些问题?
  7. 没有并发经验,但是面试中经常被问到高并发,怎么破局?
  8. 神奇的 SQL 之 HAVING → 容易被轻视的主角
  9. 小心避坑:MySQL分页时使用 limit+order by 会出现数据重复问题
  10. java 不能用 random,关于Java中Random的一些使用细节