Python爬虫之基础篇

关于Python的基本语法就不多说了,这里直接从各个小的程序开始,本文会不断地进行更新,一步步来走进Python~

同时也希望各位可以给点好的建议哈~


一、在Kali Linux中安装sublime text 3:

先下载sublime text 3,然后到下载的目录中执行以下命令即可:

dpkg -i ./sublime-text_build-3126_amd64.deb


二、Socket模块:

在导入socket时有两种方式,一个是import socket,然后在调用socket()方法的时候需要在前面加上socket.,如果是from socket import socket则不需要添加,因为已经导入了socket模块socket方法;当然另一个方式可以更简单,即from socket import *,导入socket模块所有的方法。

Python支持的套接字:AF_UNIX,AF_NETLINK,AF-INET(常用的基于网络的套接字)。

socket.socket()函数用于创建套接字。

socket.bind()函数用于绑定地址(主机,端口)到套接字。

socket.listen()函数用于开始TCP监听。

socket.accept()函数用于等待接收客户端的连接。

socket.connect()函数用于主动进行TCP连接。

socket.recv()函数用于接收TCP数据。

socket.send()函数用于发送TCP数据。

socket.sendall()函数用于完整发送TCP数据。

socket.close()函数用于关闭套接字。

1、简单模拟C/S模型进行通信:

分为两部分,一个为server端的程序,另一个为client端的程序。

socketserver.py:

#!/usr/bin/python
#coding=utf-8
from  socket import *
from time import ctime

def main():
	s = socket(AF_INET,SOCK_STREAM)
	s.bind(('',1234))
	s.listen(5)
	while True:
		print 'Waiting for connection...'
		c,addr = s.accept()
		print '...connected from:',addr
		while True:
			data = c.recv(1024)
			if not data:
				break
			print 'Client '+data
			rdata = raw_input('Some words to send : ')
			if not rdata:
				break
			time = ctime().split(' ')[4]
			t = time.split(':')[0]+':'+time.split(':')[1]+':'+time.split(':')[2]
			text = t + ' : ' +rdata
			c.send(text)
	c.close()
	s.close()

if __name__ == '__main__':
	main()

简单地说一下,bind()函数的参数是一个地址,是(IP,port)这种形式的,其中IP为空即指定为本机,后面的端口的类型记得是int型才可以,若是通过输入的方式获得则需要通过int()函数来进行类型的转换。其中调用了time库的ctime函数来获取当前时间,对其再调用split()函数来进行切割获得时:分:秒这种形式的显示。

socketclient.py:

#!/usr/bin/python
#coding=utf-8
from socket import *
import sys
from time import ctime

def main():
	try:
		url = sys.argv[1]
		port = int(sys.argv[2])
		addr = (url,port)
		c = socket(AF_INET,SOCK_STREAM)
		c.connect(addr)
		while True:
			text = raw_input('Some words to send : ')
			if not text :
				break
			time = ctime().split(' ')[4]
			t = time.split(':')[0]+':'+time.split(':')[1]+':'+time.split(':')[2]
			txt = t+' : '+text
			c.send(txt)
			data = c.recv(1024)
			if not data:
				break
			print 'Server '+data
		c.close()
	except:
		print 'Usage : ./socketclient.py [URL] [PORT] '

if __name__ == '__main__':
	main()

这里的参数port的输入需要对其调用int()函数来转换类型。

运行结果:




2、接着可以进一步将程序改为实现简单的远程控制:

socketserver.py:

#!/usr/bin/python
#coding=utf-8
from  socket import *
from time import ctime
from subprocess import Popen,PIPE

def main():
	s = socket(AF_INET,SOCK_STREAM)
	s.bind(('',1234))
	s.listen(5)
	while True:
		print 'Waiting for connection...'
		c,addr = s.accept()
		print '...connected from:',addr
		while True:
			data = c.recv(1024)
			if not data:
				break
			# print 'Client '+data
			# rdata = raw_input('Some words to send : ')
			# if not rdata:
			# 	break
			time = ctime().split(' ')[4]
			t = time.split(':')[0]+':'+time.split(':')[1]+':'+time.split(':')[2]

			cmd = Popen(['/bin/bash','-c',data],stdin=PIPE,stdout=PIPE)
			rdata = cmd.stdout.read()

			text = '[ ' + t + ' ] : ' +rdata
			c.send(text)
	c.close()
	s.close()

if __name__ == '__main__':
	main()

这里主要用到了一个subprocess库的Popen和PIPE方法,其中subprocess是用来启动一个新的进程并且与之通信,其最简单的用法就是调用shell命令,它定义了一个类: Popen,用来创建进程并与进程进行复杂的交互。调用Popen函数的先是到/bin/bash路径下即bash shell中通过-c参数来说明是传递一条命令进去执行,其中的参数stdin、stdout都设置为管道PIPE,然后再通过调用stdout的read()函数来读取命令执行后的数据,从而整个地实现从后台来执行进程。

socketclient.py:

#!/usr/bin/python
#coding=utf-8
from socket import *
import sys
# from time import ctime

def main():
	try:
		url = sys.argv[1]
		port = int(sys.argv[2])
		addr = (url,port)
		c = socket(AF_INET,SOCK_STREAM)
		c.connect(addr)
		while True:
			text = raw_input('Please enter a command : ')
			if not text :
				break
			# time = ctime().split(' ')[4]
			# t = time.split(':')[0]+':'+time.split(':')[1]+':'+time.split(':')[2]
			# txt = t+' : '+text
			c.send(text)
			data = c.recv(1024)
			if not data:
				break
			# print 'Server '+data
			print data
		c.close()
	except:
		print 'Usage : ./socketclient.py [URL] [PORT] '

if __name__ == '__main__':
	main()

运行结果:



三、Requests模块:

该模块没有默认安装,需要输入:pip install requests

发送网络请求:

>>>r = requests.get('http://www.abc.com')

>>>r = requests.post('http://www.abc.com')

>>>r = requests.put('http://www.abc.com')

>>>r = requests.delete('http://www.abc.com')

>>>r = requests.head('http://www.abc.com')

>>>r = requests.options('http://www.abc.com')

为URL传递参数:

>>>payload = {'key1':'value1','key2':'value2'}

>>>r = requests.get('http://www.abc.com',params=payload)

响应内容:

>>>r = requests.get('http://www.abc.com')

>>>r.text

>>>r.encoding 'utf-8'

二进制响应内容:

>>>r = requests.get('http://www.abc.com')

>>>r.content

定制请求头:

>>>url = 'http://www.abc.com'

>>>headers = {'User-Agent':'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0'}

>>>r = requests.get(url,headers=headers)

复杂的POST请求:

>>>payload = {'key1':'value1','key2':'value2'}

>>>r = requests.post('http://www.abc.com',data=payload)

响应状态码:

>>>r = requests.get('http://www.abc.com')

>>>r.status_code

响应头:

>>>r = requests.get('http://www.abc.com')

>>>r.headers

Cookies:

>>>r.cookies

>>>r.cookies['cookie name']

超时:

>>>requests.get(‘http://www.sina.com’,timeout=0.001)

错误和异常:

遇到网络问题(如DNS查询失败、拒绝连接等)时,Request会抛出一个ConnectionError异常;

遇到罕见的无效HTTP响应时,Requests则会抛出一个HTTPError异常;

若请求超时,则抛出一个timeout异常。

1、简单模拟HTTP的GET请求:

#!/usr/bin/python
#coding=utf-8
import requests
import sys
from time import time

def saveFile(name,data):
	f = open(name,'w')
	f.write(data)
	f.close()

def resetsys():
	reload(sys)
	sys.setdefaultencoding('utf-8')

def main():
	try:
		url = sys.argv[1]
		resetsys()
		r = requests.get(url)
		text = r.text
		filename = str(time())
		saveFile(filename,text)
		print 'Save successfully. '
	except:
		print 'Usage : ./get.py [URL]'

if __name__ == '__main__':
	main()

这里将GET请求的内容保存到以时间命名的文件中,因为时间值为int型需要通过str()函数将其转换为字符串的形式,其中会出现错误需要定义一个resetsys()函数来reload重新加载sys库,再将其默认的编码形式改为utf-8即可。

运行结果:



2、简单地通过GET请求获取服务器的信息:

#!/usr/bin/python
#coding=utf-8
import requests
import sys

def main():
	try:
		url = sys.argv[1]
		r = requests.get(url)
		print 'Server : '+r.headers.get('Server')
		print 'X-Powered-By : '+str(r.headers.get('X-Powered-By'))
	except:
		print 'Usage : ./getBSCInfo.py [URL]'

if __name__ == '__main__':
	main()

这里通过Requests的get方法的headers的get()函数来实现获取相关的信息,其中获取Lang信息是需要添加str()函数进行转换类型,因为当查询的网页没有对应的值时该返回值为空会报错,而调用该函数后则会输出None而不是出错。

运行结果:



四、OS模块:

os.name():判断现在正在实用的平台,Windows 返回 ‘nt'; Linux 返回’posix'

os.getcwd():得到当前工作的目录

os.listdir():指定所有目录下所有的文件和目录名

os.remove():删除指定文件

os.rmdir():删除指定目录

os.mkdir():创建目录

os.path.isfile():判断指定对象是否为文件。是返回True,否则False

os.path.isdir():判断指定对象是否为目录。是True,否则False

os.path.exists():检验指定的对象是否存在。是True,否则False

os.path.split():返回路径的目录和文件名

os.getcwd():获得当前工作的目录(get current work dir)

os.system():执行shell命令

os.chdir():改变目录到指定目录

os.path.getsize():获得文件的大小,如果为目录,返回0

os.path.abspath():获得绝对路径

os.path.join(path, name):连接目录和文件名

os.path.basename(path):返回文件名

os.path.dirname(path):返回文件路径

到指定路径执行指定脚本文件:

chdir(getcwd() + ‘\\test’)

system(‘./test.py’)

1、通过ssh连接到指定目录指定指定脚本:

#!/usr/bin/python
#coding=utf-8
from os import *
import sys

def main():
	try:
		path = sys.argv[1]
		filename = sys.argv[2]
		chdir(path)
		system('./'+filename)
	except:
		print 'Usage : ./sshOS.py [File Path] [Filename] '

if __name__ == '__main__':
	main()

在system()函数中运行Python文件时需要在前面加上“./”来表示运行即可。

先在BT5上开启ssh服务:service ssh start

然后在Kali通过命令ssh连接到BT5上,然后直接运行该脚本并指定参数说明到哪个目录下运行哪个文件,如下:



五、多线程:

线程与进程:进程是程序的一次执行;所有的线程运行在同一个进程中,共享相同的运行环境。

Python多线程的模块有三个,即thread、threading和Queue。

1、thread模块简单实现局域网主机发现ping扫描:

thread模块通过调用start_new_thread(function,args kwargs=None),产生一个新的线程,但缺点是控制不了线程数。

#!/usr/bin/python
#coding=utf-8
import thread
from subprocess import Popen,PIPE 
import time

def hostscan(ip):
	cmd = Popen(['/bin/bash','-c','ping -c 3 '+ip],stdin=PIPE,stdout=PIPE)
	txt = cmd.stdout.read()
	if 'ttl' in txt:
			print ip+' is UP. '

def main():
	for i in xrange(1,255):
		ip = '10.10.10.'+str(i)
		thread.start_new_thread(hostscan,(ip,))
		time.sleep(0.1)

if __name__ == '__main__':
	main()

主要是通过subprocess模块来运行ping命令实现功能的,其中通过判断返回得到数据中是否有ttl即time-to-live值来判断主机是否存活,当然可以将命令换成任意的扫描命令都可以,甚至可以各种命令组合来提高扫描的准确度。需要注意的点就是在调用多线程时需要一个time模块sleep()函数来进行延迟。

运行结果:



2、threading模块简单实现局域网主机发现arping扫描:

该模块有两种方式来创建线程:一种是通过继承Thread类,重写其run方法;另一种是创建一个threading.Thread对象,在其初始化函数中将可调用对象作为参数传入。

下面应用threading.Thread对象,其有两个参数,一个为target指定执行的函数,另一个为args指定输入的参数,主要参数输入外部要添加括号。在创建完对象之后还需要调用start()函数来开始线程运行。

#!/usr/bin/python
#coding=utf-8
import threading
from subprocess import Popen,PIPE 
import time

def hostscan(ip):
	cmd = Popen(['/bin/bash','-c','arping -c 3 '+ip],stdin=PIPE,stdout=PIPE)
	txt = cmd.stdout.read()
	if 'bytes from' in txt:
			print ip+' is UP. '

def main():
	for i in xrange(1,255):
		ip = '10.10.10.'+str(i)
		t = threading.Thread(target=hostscan,args=(ip,))
		t.start()
		time.sleep(0.1)

if __name__ == '__main__':
	main()

这里将ping命令换成arping命令,即从三层的主机扫描换为二层的主机扫描,其中因为回复的内容不一样,“ttl”需要换为“bytes from”,从结果比较可以看到,不同层次的主机扫描的发现结果是不太一样的。

运行结果:



3、Queue模块实现nmap主机发现扫描:

Queue模块主要可以解决生产者-消费者问题,简单地说可以实现队列,即有序地进行线程。

其中Queue模块的一些函数:qsize()、empty()、full()、put()、get()

下面使用Queue模块结合threading模块来实现nmap主机发现扫描,其中需要写一个nmapscan类,对里面的初始化方法__init__和run方法进行重写;在主函数中一个线程数组、线程数和Queue对象,并将nmapscan类调用每个Queue对象的值添加到线程数组中,再通过start()和join()函数来开始并加入队列线程,这样程序就能有序地执行。

#!/usr/bin/python
#coding=utf-8
import threading
from subprocess import Popen,PIPE 
import Queue

class nmapscan(threading.Thread):
	def __init__(self,queue):
		threading.Thread.__init__(self)
		self._queue = queue

	def run(self):
		while  not self._queue.empty():
			ip = self._queue.get()
			cmd = Popen(['/bin/bash','-c','nmap -sn '+ip],stdin=PIPE,stdout=PIPE)
			txt = cmd.stdout.read()
			if 'Host is up' in txt:
				print txt

def main():
	threads = []
	threads_count = 10
	queue = Queue.Queue()
	for i in xrange(1,255):
		ip = '10.10.10.'+str(i)
		queue.put(ip)
	for i in range(threads_count):
		threads.append(nmapscan(queue))	
	for i in threads:
		i.start()
	for i in threads:
		i.join()

if __name__ == '__main__':
	main()

这里直接调用nmap命令-sn参数,即只进行主机发现而不进行端口扫描,从结果可见nmap扫描结果比上面两个命令都准确一些。

运行结果:



六、MySQLdb模块:

该模块没有默认安装,先下载安装MySQLdb模块:https://sourceforge.net/projects/mysql-python/?source=typ_redirect

tar –xfz MySQL−python−1.2.1.tar.gz

cd MySQL-python-1.2.1

apt-get install python-setuptools

apt-get install python-dev

apt-get install libmysqlclient-dev或apt-get install libmariadbclient-dev

python setup.py install


数据库连接对象connection,创建方法:MySQLdb.Connect(参数),其中参数有:

host:MySQL服务器地址,默认是本地主机

use:用户名,默认是当前用户

passwd:密码,默认为空

db:数据库名

port:MySQL服务器端口,默认是3306

charset:连接编码


Connection对象支持的方法:

cursor():使用该连接创建并返回游标

commit():提交当前事务

rollback():回滚当前事务

close():关闭数据库连接


Cursor对象支持的方法:execute(op[,args])、fetchone()、fetchmanv(size)、fetchall()、rowcount、close()


如果忘记了MySQL的用户密码,可以重设:

mysql

use mysql

update user set password=PASSWORD('admin') where User='root';

flush privileges;

service mysql start

1、简单实现连接本地MySQL数据库并执行SQL语句:

#!/usr/bin/python
#coding=utf-8
import MySQLdb
from sys import argv

def main():
	try:
		conn = MySQLdb.connect(
			host = argv[1],
			port = 3306,
			user = argv[2],
			passwd = argv[3],
		)
		cus = conn.cursor()
		sql = 'select concat_ws(char(32,58,32),user(),version(),@@global.version_compile_os)'
		cus.execute(sql)
		print cus.fetchone()
		cus.close()
		conn.close()
	except:
		print 'Usage 
  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值