使用python进行爬虫工作的步骤与教程
- 概述
-
- 框架
- 分析步骤
首先我会先介绍一下爬虫的步骤和框架等基本信息,文中的代码可以去github上下载,或者去csdn的下载链接下载。首先给出链接,在后面的例子前面我会再次给出相应的链接。
第一个例子,静态网页爬取:
csdn下载:
静态网页爬取
github链接:
静态网页爬取selenium版
github链接:豆瓣网爬取
csdn下载:豆瓣网爬取
github链接:校花网爬取
csdn下载:校花网爬取
csdn下载:煎蛋网爬取
概述
使用python来对网页进行爬取,其步骤都比较固定,主要是要分析网页的结构等,再根据网页的结构来选择爬取的方法。 如果网页是静态的网页,爬取工作自然就非常轻松了,直接访问url,在其返回的response里用bs4来进行关键信息的提取或者使用re(正则表达式)来进行提取都可以获得想要的数据。
框架
在最开始我使用的是最原始的urllib来进行爬取,之后学习了requests来进行爬取。现成的框架有很多,比如scapy等,我觉得,框架只是一种工具,不需要纠结到底用哪个框架。如果你觉得用它来做开发,用得顺手,那么这个框架就很好了。
包括后面的selenium+PantomJS,是一种无界面浏览器的自动化测试工具,也是爬虫界的重量级武器了,对于很多复杂的网页,在分析它的网路的时候不好分析或者不会分析的时候,直接上selenium+pjs,可以简单暴力地获取你想要的信息。
分析步骤
首先,先要明确你需要爬取的东西是什么。比如你想要爬取某个网页上的图片(或者某个网页上的数据信息,这里以图片为例进行说明),那么我常用的步骤是:
1.先查看网页源代码(以静态网页为例,动态网页看2)
看在源代码里面有没有图片的src地址,如果有,那么这种静态网页就相对很好爬取了,这种网页就是开发人员在开发网页的时候就把网页中的所有图片都已经写死在代码里面了。如果你想要爬取这个网页中的图片信息并保存到本地的话,那么直接访问这个url,然后返回的response里面就是它的网页源代码,使用正则表达式或者bs4直接提取相关信息即可。
首先添加头部信息(用于验证你这个操作是人为的,虽然是用代码来实现访问网页,但是我们可以伪装成人来访问,这样不会被反爬)
csdn下载:静态网页爬取
github链接:静态网页爬取selenium版
#响应头信息
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36'
}
#目标url
url = 'http://sso.jwc.whut.edu.cn/Certification//login.do'
- 1
- 2
- 3
- 4
- 5
- 6
我是拿的我们学校的教务处网站做例子。首先头部信息里面是你浏览器的版本等信息,你可以用我提供的这个,或者你是用你自己的,这个你可以很容易的获取到。
#获取原网页返回的html
def get_html(url,userName,password):
#添加进入教务处的信息
data = {
'systemId':'',
'xmlmsg':'',
'userName':userName,
'password':password,
'type':'xs'
}
#将信息格式编码为html格式
data = parse.urlencode(data).encode('utf-8')
#提交请求
req = request.Request(url=url,headers=headers,data=data)
response = request.urlopen(req)
#获取网页html代码
html = response.read()
return html
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
之后,我定义了一个函数,这个函数直接执行,就能返回静态网页的网页源代码了,然后进行关键信息的爬取。首先,data这个是你要分析的,这个data信息的获取方法如下:
以我的这个网址为例,我是用的是google浏览器,那么你首先进入到这个登录界面,然后右键,检查,会跳出这么一个界面。
右侧选择到network,出现这个界面之后,输入账号信息,点击登录,如果登录成功,右侧右面空白处会出现信息,点击login(大多数叫这个)文件,然后里面会有一系列的data数据,复制即可。
对于静态网页获取到的信息,直接用bs4或者正则就可以提取到数据了(不再讲解正则和bs4)。
2.动态网页爬取
先讲不使用selenium_PJs的:
首先,如果网页是那种底部有“点击加载更多”这种字样的,一般都是当你点击的时候触发请求,去某个接口去访问数据,这种的只需要弄到它的接口地址就好。还是选择刚才的network,当你点击了那个按钮之后,你的xhr里面会多出文件(这里切换到xhr)
这个xhr文件打开,里面会有接口的地址,直接去接口地址访问数据。接口使用get请求,那么你可以更改这个get请求的数据,例如图片数量等从而获取指定数量的图片等信息(不过这个数量一般设置有上限,比如100,如果你把这个get信息里的图片数量改到100以上如1000,那么返回的还是100张)
其实动态网页最主要的操作,也就是比静态网页多了一个分析的过程。静态网页中的数据在代码里面写死了,所以你获得源代码就可以了。而动态网页源代码里面没有你的数据信息,因此你光获取到源代码是没有用的。所以你需要打开network界面,当你点击之后(例如翻页操作),会有http请求出现在这个地方,你需要对这些http请求(也就是这里出现的文件)进行操作,打开它,然后看里面的数据,有没有包含它的后台地址或者接口等,然后直接去访问那个url,这样获取到的源代码才会包含信息(例如图片的链接),之后再操作。
3.重量级武器:自动化测试模块selenium+PantomJS
一个使用selenium的例子:
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
class Spider:
def __init__(self,browser,email,password):
self.url = 'http://sso.jwc.whut.edu.cn/Certification//toIndex.do'
self.browser = browser
self.email = email
self.password = password
def login(self):
self.browser.get(self.url)
try:
email = WebDriverWait(self.browser,10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "#textfield"))
)
password = WebDriverWait(self.browser, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "#textfield2"))
)
submit = WebDriverWait(self.browser, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "#loginForm > div:nth-child(7) > button"))
)
email.send_keys(self.email)
password.send_keys(self.password)
submit.click()
except TimeoutException:
print('连接超时,已退出')
def main():
email = input('请输入你的账号:')
password = input('请输入你的密码:')
spider = Spider(browser,email,password)
spider.login()
if __name__ == '__main__':
main()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
其实这个东西是自动化测试的部分,也就是你只要输入代码之后,它会按照你的代码一步一步执行。开始使用selenium不使用pantomjs(例如你可以使用chromedriver),这样一开始会有界面,你可能会懂一点。
网页的元素是有id或者类或者别的东西的,你可以使用它特定的标签来唯一识别它。比如你可以先识别到输入框,再识别到确定按钮。那么你就可以在代码里面用selenium(不讲解使用教程)来让它现在输入框里输入“百度”,然后点击确定。在你这些代码都写好之后,运行,那么(如果你开的不是无界面浏览器pjs的话,这里以chrome为例)你会看到google浏览器自动打开,然后输入框里自动输入了“百度”,然后自动跳转。这些都是你代码所实现的功能。如果你是pjs的话,也就是无界面浏览器,那么就不会出现界面,直接返回结果给你。所以你可以先用chrome来进行实验,最后使用pjs来真正使用,因为这样会提高速度。
那么,这个有什么用呢?解答一下,能在网页上显示的东西,都是一个元素,那么
从刚才的network切换到element,你可以看到这个网页各个地方都对应一个element(注意:这个element里面的源代码并不是你用刚才静态网页访问所返回的源代码)。如果是动态网页,那么你使用刚才静态网页爬取的方法去访问这个url是不会返回给你有价值的信息的。例如它会返回给你一个网页源代码,但是这个源代码里面根本没有图片的src信息。但是,在被解析呈现到浏览器上时,也就是出现这个element时,这个图片的src是会出现的。也就是说,只要能获取到这个element的源代码,那所有网页都不怕了,想爬什么爬什么。怎么获得呢?
使用selenium+pjs可以直接获取到这个element代码。
以下是另外一个使用selenium的例子
from urllib import request
from selenium import webdriver
import threading
#设置最大线程锁:10个线程
thread_lock = threading.BoundedSemaphore(value=10)
#通过selenium获得图片src
def getsrc(url):
img = []
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36'
}
#chrome的位置
path = 'F:\study\python3.5\chromedriver.exe'
#进入chromedriver设置
options = webdriver.ChromeOptions()
#设置不弹窗
options.add_experimental_option("excludeSwitches", ["ignore-certificate-errors"])
#设置头部信息
options.add_argument(headers)
browser = webdriver.Chrome(executable_path=path,chrome_options=options)
browser.get(url=url)
for i in range(1,27):
imgpath = "//div[@id='wrapper']/div[2]/div[1]/div[2]/ol/li[{}]/div/div/div[2]/p/a".format(i)
if browser.find_element_by_xpath("//div[@id='wrapper']/div[2]/div[1]/div[2]/ol/li[{}]".format(i)).get_attribute('id') != 'adsense':
src = browser.find_element_by_xpath(imgpath).get_attribute('href')
if src != 'javascript:;':
img.append(src)
print(src)
print('1')
browser.quit()
return img
#获得网页响应
def getresponse(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36'
}
req = request.Request(url=url,headers=headers)
response = request.urlopen(req)
data = response.read()
return data
#下载器
def download(data,name):
with open(name,'wb') as f:
f.write(data)
#解锁
thread_lock.release()
#主函数
def grabpic():
#初始url
first_url = 'http://jandan.net/ooxx/page-%i#comments'
imgsrcs = []
index = 0
for i in range(83,88):
#执行函数,得到网页响应
response = getsrc(first_url%i)
imgsrcs.extend(response)
for img in imgsrcs:
index = index + 1
data = getresponse(img)
#上锁
thread_lock.acquire()
t = threading.Thread(target=download,args=(data,str(index)+'.jpg'))
#download(data,str(index)+'.jpg')
t.start()
if __name__ == '__main__':
grabpic()
print('1')
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
所以说这个重量级武器很无敌了。
最后附上一些爬虫代码:
github链接:豆瓣网爬取
csdn下载:豆瓣网爬取
github链接:校花网爬取
csdn下载:校花网爬取
csdn下载:煎蛋网爬取