Python爬虫练手小项目(2)-扫免费ip

hi,回来了,时隔许久,又诈尸了,这次跟大家分享一个python爬虫的基础练习,上网扒免费的代理。这次不涉及代理怎么使用,和测试,单纯的与大家分享一些python语言的编写,以及想法的实现。

Lets go:

目标:

本次供我们学习的目标网站是,西刺代理。网站如下,一般出于使用代理都是为了隐藏身份,所以我们的目标是爬取里面的高匿代理,网站已经替我们已经收集了免费高匿代理。如下:跳转到这个页面(代理质量你懂的~)

分析:

分析信息来源:

浏览器调用f12,查看Network面板,访问该页面,浏览数据包的传递。

观察知道,信息来源于传递过来的html页面,让我们再观察他的返回信息(Response)。

可以确认,我们需要获取的数据来源与这个html。接下来我们需要分析如何从这个html里面提取我们想要的信息。

2. 信息匹配:

提取html信息的方法在python中有许多实现,我习惯使用xpath对网页信息进行提取。当然你也可以使用你熟悉的方法。

我们需要提取的信息在这个属性id="ip_list"的table标签中,注意,Google浏览器出于一种对页面结构的优化会在上面加上了tbody标签,如图可以看到,但是在实际的页面结构中并没有,所以如果直接使用上面提供的xpath会匹配不到信息。

好了,我们知道信息在这个table标签里面的tr标签中,但是你们发现了没,第一个tr标签是一些信息的说明,在实际提取中我们是不需要的,但是下面的包含所需信息的tr标签们,并没有什么合适的标识统一我们匹配,意味着我们的for循环需要一点改动。(这边我就先提个醒,后面实现的时候我再讲思路。)

我们要爬取的信息有这个有 代理的地址(IP+端口),类型(HTTP、HTTPS) 、以及过滤掉所有速度、连接时间>1秒 的代理。

至此,信息匹配部分分析完毕。

3. 实现翻页。

(这边我就直接说了),我们通过在网页上翻页观察出每次翻页只是在url上进行了页码的变化。比如:

第一页:http://www.xicidaili.com/nn/1

第二页:2

第三页:。。。。。。。

代码实现:

# !/usr/bin/python # -*- coding:utf-8 -*- """ (1):思路抓取所有的代理id,做好区分http还是https的代理。 (2): 代理洗澡,过滤掉所有反应时间大于1秒的代理。 (3): 测试代理:。。。 """ __author__ = Zisc import requests from lxml import etree import time import json def start(start_url, n): headers = { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36, } for i in range(1, n+1): try: response = requests.get(start_url.format(i), headers=headers) if response.status_code == 200: yield response.text except Exception as e: _ = e# 占位,编写规范 print(发生了未知错误) def match_data(content): data_contains = [] rsp = etree.HTML(content) for i in range(2, 102): one_item = rsp.xpath(fstring(//*[@id="ip_list"]/tr[{i}])).split() one_item_speed = rsp.xpath(f//*[@id="ip_list"]/tr[{i}]/td[7]/div/@title)[0] one_item_link_speed = rsp.xpath(f//*[@id="ip_list"]/tr[{i}]/td[8]/div/@title)[0] proxy_data = {"proxy": ":".join([one_item[0], one_item[1]]), "proxy_scheme": one_item[-4], speed: one_item_speed, link_speed: one_item_link_speed} proxy_data = clean_data(proxy_data) if proxy_data:# 如果不为空,没被过滤掉则加入容器 data_contains.append(proxy_data) return data_contains def clean_data(data): import re data_speed = eval(re.findall(\d\.\d+, data.get(speed, ))[0]) data_link_speed = eval(re.findall(\d\.\d+, data.get(link_speed, ))[0]) if data_speed < 1 and data_link_speed < 1: cleaned_data = {proxy: data.get(proxy, ), proxy_scheme: data.get(proxy_scheme, )} return cleaned_data else: return def save_data(file_name, data): with open({}.json.format(file_name), a, encoding=utf-8) as f: file_line = json.dumps(data) f.write({}.format(file_line)) if __name__ == __main__: count = 1# 计数 # 启动链 start_url = {} # 输入保存的文件名 file_name = input(请输入保存的文件名:) climb_page = int(input(请输入你要摸多少页:)) all_data = []# 用于存放所有的信息 for i in start(start_url, climb_page): print(正在执行抓取第%d页 % count) data = match_data(i) all_data.extend(data) count += 1 time.sleep(3) save_data(file_name, all_data)# 定义文件名,接受所有的信息写入文件

功能说明:

1. start (start_url, n) :

start_url: 启动时的url,带格式化参数

n: 需要翻取的页面,配合start_url产生需要request的url

启动函数,访问目标网站,获取其html文本信息,。这边访问需要加请求头,不加的话是无法正常访问的(不信邪可以去掉,自个捣腾玩玩),也不用多加,只需要加UA就好。这个函数我使用了生成器的功能,(简单来说,可以for循环,每一次循环,会返回一个这个网站的html文本信息)

2. match_data(content):

content: 接收start_url函数传来的html文本,用于提取信息。

匹配函数,提取所需内容。其中这里的的for循环是为了解决上面信息匹配中的一个问题,观察页面发现每table下有101个tr标签,但是第一个tr标签我们是不需要的所以每一页总共有100个信息我们需要提取(可能有更改好的方法,只是我没想到,欢迎交流。),由于有的内容信息提取十分繁杂,这边我就用了xpath中的string()提取。这边做个简单的说明,one_item返回的内容如下。

需要提取的信息就用dict类型来存储,one_item_speed则是速度,one_item_link_speed则是链接速度,最后在做个信息的规整。然后进入过滤clean()函数。过滤出速度,连接速度大于1秒的IP数据。

3. clean_data(data):

data: 接受传递过来的数据(类型为字典)

过滤出速度,连接速度大于1秒的IP数据,提取前的信息如下:

这边用正则提取出所需信息,提取出speed, link_speed中的信息,然后做数据转换进行数据的过滤。符合要求则返回数据,否则则返回空。

4.save_data(file_name, data):

file_name : 接收一个字符串参数作为保存的文件名。

data: 接收传递过来的数据,写成json信息

保存写入文件函数,写入数据。

演示:

最后:

只做学习交流,如果能在你python学习路上带来帮助那再好不过了,之前我一直纠结于怎样才算学会一门编程语言,也很迷茫,后面看到一个老哥的一句说——语言只是工具,只是实现你的思路代码的工具。所以说想法都没再好的语言也是摆设,学习路上共勉吧~