网页抓取 加密html(一个爬虫抓取自己的借阅文件查看的过程及注意事项)

优采云 发布时间: 2022-04-17 16:21

  网页抓取 加密html(一个爬虫抓取自己的借阅文件查看的过程及注意事项)

  2021-05-19

  Python爬虫实战---抓取库借阅信息

  原创作品,转载请注明出处:Python爬虫实战---抓取库借阅资料

  前段时间在图书馆借了很多书,借多了很容易忘记每本书的到期日。一直担心会违约,影响以后借阅,但又懒得老是登录学校图书馆借阅系统。查,所以我打算写一个爬虫来抓取我的借阅信息,把每本书的到期日爬下来,写成一个txt文件,这样每次忘记的时候可以打开txt文件查,而且每我借的时候。如果信息发生了变化,只要再次运行程序,原来的txt文件就会被新的文件覆盖,里面的内容也会被更新。

  使用的技术:

  Python版本为2.7,同时使用了urllib2、cookielib和re三个模块。urllib2 用于创建请求,抓取网页信息,返回类似文件类型的响应对象;cookielib用于存储cookie对象,实现模拟登录功能;re 模块提供了对正则表达式的支持,用于匹配爬取的页面信息,得到你想要的信息。

  抓取页面:

  使用 urllib2 简单地抓取网页的过程非常简单:

  1 import urllib2

2 response = urllib2.urlopen("http://www.baidu.com")

3 html = response.read()

  urllib2 中的 urlopen() 方法,从字面意思可以知道是打开一个 URL(统一资源定位器)地址。上例中传入了百度主页的地址,遵循HTTP协议。除了 HTTP 协议,urlopen() 方法还可以打开遵循 ftp 和文件协议的地址,例如:

  1 response = urllib2.urlopen("ftp://example.com")

  除了 URL 参数,urlopen() 方法还接受数据和超时参数:

  1 response = urllib2.urlopen(url ,data ,timeout)

  其中,data是打开网页时需要传入的数据。例如,在打开登录界面时,往往需要传入用户名、密码等信息。当您登录下面的图书馆系统时,您将看到它的使用情况;timeout是设置超时时间,即如果页面在一定时间后没有响应,就会报错;在 urlopen() 方法中,data 和 timeout 不是必须的,可以填也可以不填。注意:当页面需要有数据传入时,需要数据。

  可以看出,打开网页时,有时需要传入多个参数,而HTTP协议是基于request和response的,即客户端发送请求,服务器返回响应(response),所以在使用 urlopen() 方法时,往往会构造一个请求对象,并作为参数传入。请求对象包括url、data、timeout、headers等信息:

  1 import urllib2

2 request = urllib2.Request("http://www.baidu.com")

3 response = urllib2.urlopen(request)

4 html = response.read()

  这段代码的结果和上面得到的结果是一样的,只是逻辑上更清晰更清晰。

  Cookie 的使用:

  在访问一些网站时,网站需要在客户端本地存储一些数据和信息(加密),并在下次请求时返回给服务器,否则服务器会拒绝它的请求,这些数据存储在本地 cookie 中。比如访问学校图书馆系统时,需要登录,登录完成后,服务器会在本地存储一些加密数据在cookie中。当客户端发送查询借款信息的请求时,会将相关的cookie中的数据一起发送给服务器,服务器判断cookie信息并允许访问,否则拒绝该请求。

  Cookielib 模块提供了用于捕获和存储 HTTP cookie 数据的 CookieJar 类,因此要创建 cookie,只需创建一个 CookieJar 实例:

  1 import cookielib

2 cookie = coolielib.CookieJar()

  创建cookie后一切正常吗?没那么简单。我们需要做的是发送登录请求,记录cookie,然后发送请求读取借阅信息,并将cookie信息反馈给服务器。完成这一系列操作,原来的 urlopen() 方法已经不能胜任了。好在 urllib2 模块还提供了一个 OpenerDirector 类,它可以接受一个 cookie 处理程序作为参数来实现上述功能,而这个 cookie 处理程序可以通过 HTTPCookieProcessor 类实例化一个 cookie 对象来获得。即首先通过实例化HTTPCookieProcessor获得一个cookie处理器handler,然后将此handler header作为参数传递给OpenDirector来实例化一个可以捕获cookie数据的opener。代码如下:

  1 import urllib2

2 import cookielib

3

4 cookie = cookielib.CookieJar()

5 handler = urllib2.HTTPCookieProcessor(cookie)

6 opener = urllib2.build_opener(handler)

7 response = opener.open("http://www.baidu.com")

  登录图书馆系统:

  至此,我们就可以抓取图书馆的借阅信息了。我们来看看命中库登录界面:

  

  首先,在火狐浏览器中,使用httpfox插件监控网络,看看需要向服务器发送哪些数据才能登录这个页面:

  

  输入登录账号和密码,打开httpfox插件,点击start开始监控,然后点击登录按钮登录:

  

  上图是登录后的页面,以及整个登录过程中抓取的信息。选择第一个捕获的信息,点击下面的headers选项卡,可以看到登录这个页面需要发送的一些数据。有一些网站,对于访问它们的请求,需要检查数据头(Headers),只有头信息符合要求才允许访问。登录图书馆系统时,可以先尽量不发送数据头。如果可以访问成功,说明没有header检查。数据发送方式为GET,即只需要在登录请求后面加上要发送的数据信息即可。在Headers选项卡的Request-Line属性中,问号前面是登录请求“GET /lib/opacAction.do”,

  接下来单击 QueryString 选项卡以查看 GET 方法发送的数据:

  

  需要传输的数据包括5项,存储在字典类型中,通过urlencode()方法编码后可以直接添加到登录URL中,所以最终发送给服务器的请求为:

   1 import urllib

2

3 loginURL = 'http://202.118.250.131/lib/opacAction.do'

4 queryString = urllib.urlencode({

5 'method':'DoAjax',

6 'dispatch':'login',

7 'registerName':'',

8 'rcardNo':'16S137028 0',

9 'pwd':'******'

10 })

11 requestURL = self.loginURL + '?' + self.queryString

  获取请求URL后,即可模拟登录图书馆系统。在模拟登录的过程中,需要使用上面提到的cookies,否则无法进行后续访问。在编码过程中,定义了一个库类,使访问过程成为一个面向对象的过程,可以根据需要实例化多个库对象,分别对多个实例进行操作。首先,库类应该有一个初始化方法(__init__)和一个获取页面的方法(getPage)。打开网页时,应该使用上面提到的 opener 实例来自动捕获和存储 cookie:

   1 import urllib

2 import urllib2

3 import cookielib

4 import re

5

6 class library:

7 def __init__(self):

8 self.loginURL='http://202.118.250.131/lib/opacAction.do'

9 self.queryString = urllib.urlencode({

10 'method':'DoAjax',

11 'dispatch':'login',

12 'registerName':'',

13 'rcardNo':'16S137028 0',

14 'pwd':'******'

15 })

16 self.requestURL = self.loginURL + '?' + self.queryString

17 self.cookies=cookielib.CookieJar()

18 self.handler=urllib2.HTTPCookieProcessor(self.cookies)

19 self.opener=urllib2.build_opener(self.handler)

20 def getPage(self):

21 request1 = urllib2.Request(self.requestURL)

22 request2 = urllib2.Request(' http://202.118.250.131/lib/opacAction.do?method=init&seq=301 ')

23 result = self.opener.open(request1)

24 result = self.opener.open(request2)

25 return result.read()

26

27 lib = library()

28 print lib.getPage()

  上面代码中,首先登录 result = self.opener.open(request1) ,登录没有异常,说明登录过程不需要检查数据头;然后使用这个self.opener.open(request1)) opener 打开借阅查询页面

  ,所以这段代码会打印出借阅查询界面的HTML代码。下图是部分打印结果:

  

  获取借款信息:

  爬取完页面信息后,接下来就是根据自己的需求匹配并存储信息了。在匹配页面信息时,我们使用正则表达式进行匹配。Python 的 Re 模块提供了对正则表达式的支持。正则表达式的使用方法可以参考这里:Python正则表达式指南

  在使用Re模块进行匹配时,往往会将正则表达式字符串编译成一个Pattern实例,然后使用Re模块中的re.findall(pattern, string)来匹配字符串string中的正则表达式。数据以列表形式返回。如果模式中有多个组,则返回的结果将是一个元组列表,例如这个正则表达式:"tb.*?width="50%">(.*?).*?.* ?.* ?(.*?).*?(.*?).*? ,公式中,每个(.*?)代表一个组,即这个公式中有3个组,匹配时返回一个A列表元组,其中每个元组有 3 个值。

  在库类中,定义获取信息的方法(getInformation),通过正则表达式匹配获取所需的数据:

  1 def getInformation(self):

2 page = self.getPage()

3 pattern = re.compile(''+

4 '(.*?).*?(.*?).*?',re.S)

5 items = re.findall(pattern,page)

  获取到需要的数据后,下一步就是将数据写入一个文本文件(txt)进行存储,以读写模式(W+)打开一个文件(library.txt),然后将数据写入文件一一个通过 write() 方法。但是,在写入信息之前,需要对捕获的信息进行一些小的处理。刚才说了,findall()方法返回一个元组列表,即[[a,b,c],[d,形式为e,f],[g,h,i]],写() 方法不能对元组进行操作,所以需要手动将元组翻译成字符串,然后保存到列表中。迭代将每个字符串写入文件:

   1 def getInformation(self):

2 page = self.getPage()

3 pattern = re.compile(''+

4 '(.*?).*?(.*?).*?',re.S)

5 items = re.findall(pattern,page)

6

7 contents = []

8 for item in items:

9 content = item[0]+' from '+item[1]+' to '+item[2]+'\n'

10 contents.append(content)

11 self.writeData(contents)

12 def writeData(self,contents):

13 file = open('libraryBooks.txt','w+')

14 for content in contents:

15 file.write(content)

16 file.close()

  至此,整个爬虫就完成了,下面粘贴完整的代码:

  你完成了:

   1 __author__='Victor'

2 #_*_ coding:'utf-8' _*_

3 import urllib

4 import urllib2

5 import cookielib

6 import re

7

8 class library:

9 def __init__(self):

10 self.loginURL='http://202.118.250.131/lib/opacAction.do'

11 self.queryString = urllib.urlencode({

12 'method':'DoAjax',

13 'dispatch':'login',

14 'registerName':'',

15 'rcardNo':'16S137028 0',

16 'pwd':'******'

17 })

18 self.requestURL = self.loginURL + '?' + self.queryString

19 self.cookies=cookielib.CookieJar()

20 self.handler=urllib2.HTTPCookieProcessor(self.cookies)

21 self.opener=urllib2.build_opener(self.handler)

22 def getPage(self):

23 request1 = urllib2.Request(self.requestURL)

24 request2 = urllib2.Request('http://202.118.250.131/lib/opacAction.do?method=init&seq=301')

25 result = self.opener.open(request1)

26 result = self.opener.open(request2)

27 return result.read()

28 def getInformation(self):

29 page = self.getPage()

30 pattern = re.compile(''+

31 '(.*?).*?(.*?).*?',re.S)

32 items = re.findall(pattern,page)

33

34 contents = []

35 for item in items:

36 content = item[0]+' from '+item[1]+' to '+item[2]+'\n'

37 contents.append(content)

38 self.writeData(contents)

39 def writeData(self,contents):

40 file = open('libraryBooks.txt','w+')

41 for content in contents:

42 file.write(content)

43 file.close()

44

45 lib = library()

46 lib.getInformation()

  以下是抓到的借款信息。不得不说,效果不是很好,但是看看还是不错的:

  

  原创作品,转载请注明出处:Python爬虫实战---抓取库借阅资料

  分类:

  技术要点:

  相关文章:

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线