python抓取动态网页(python关于python编写爬虫的一些东西是怎样的?(图))

优采云 发布时间: 2022-03-07 23:25

  python抓取动态网页(python关于python编写爬虫的一些东西是怎样的?(图))

  前段时间浏览知乎的时候,发现一篇关于用python写爬虫的帖子。这是帖子的链接

  于是想到了用python来尝试爬取一些东西。本来打算根据关键词爬取百度图片并下载,但过程中遇到障碍,暂时停止。然后去内涵段的页面结构,发现还是比较简单的

  单点,然后在下面实现一个爬虫。

  写这个程序的时候参考了博主的相关博文在知乎/pleasecallmewhy/article/details/8929576

  编写这个程序主要分为以下几个步骤:

  1.分析Inner Community的页面结构

  2.使用正则表达式查找要下载的url

  3.下载这些图片

  第一步就是第一步,也是比较关键的一步。如果页面分析不正确,则后续步骤将无法启动。

  1.打开内段子囧图片页

  我们将看到以下页面

  这个页面下面有一些我们想要的搞笑图片,但是我们首先需要得到这个页面的html文件,这里我使用python的urllib库,代码如下

  def get_html(url):

print "---------------now get html from url :" + url + "----------"

send_headers = {

'Host':'neihanshequ.com',

'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0',

'Cookie':"pksrqup=1; csrftoken=237f4451075fe45cef3a4f5449f70658; tt_webid=3379513254; uuid=\"w:33266c46f0cc4fa6944c073b1b1bccea\"",

'Connection':'keep-alive'

}

req = urllib2.Request(url ,headers=send_headers)

try:

response = urllib2.urlopen(req ,timeout = 100)

html = response.read()

return html

except urllib2.HTTPError, e:

print 'The server couldn\'t fulfill the request.'

print 'Error code: ', e.code

except urllib2.URLError, e:

print 'We failed to reach a server.'

print 'Reason: ', e.reason

else:

print 'No exception was raised.'

  需要使用 urllib 模拟使用 Firefox 的 Firebug 插件发送的信息才能看到,然后复制头部信息填入上面的头部。需要添加其中的 Cooiker。如果不添加,将无法获取 html 文件。urllib的使用具体介绍见上面博主的博客,说的很清楚。

  既然得到了html文件,我们来观察这个文件。这个html文件的结构比较清晰。

  每个帖子由一个 div 组成,然后是标题、图像和评论的另一个 div

  在class = content-wrapper的div中我们找到了这句话

  这个data-text就是图片的写法,data-pic就是图片的地址,所以我们的工作就是获取所有的data-pic和data-text(后面可以作为图片的名字)

  要解析这个 html 中的所有这两个字段,我们需要使用 python 的正则表达式。我们这里使用的非常简单。我是通过模仿得到的。具体的re教程也可以从上面的博主那里获得。

  下面是我的重新解析代码

  这样我就可以根据刚才得到的html文件解析出所有图片的地址,然后就可以在下面下载了。下载使用与urllib相关的函数。

  -----------------到此结束,就可以下载几十张图片了

  为什么只有几十张图片?

  原因是我们刚刚获取的只是首页的html文件,那么如何获取更多的html文件呢?

  我们注意到页面底部有一个Load More按钮,点击它可以获取图片。

  我们也使用萤火虫来抓取包。

  打开这个 Get 请求和结果

  问:

  响应:我们在浏览器中输入这个请求地址,得到一个json响应

  逐步展开json得到

  在 large_image 下面我们有我们需要的东西。.

  仔细观察得到的json响应,你会发现有一个min_time字段,是一个unix时间戳。而这个 min_time 正是这个下一个请求的 max_time

  这个循环可以得到所有的图片!!

  进入第一次获取的html文件,也可以找到一个

  那么我们的任务基本上就是不断的解析json文件并下载

  下面是我的第一个版本的源代码

  # -*- coding: utf-8 -*-

import urllib2

import urllib

import re

import thread

import time

import os

import random

import json

#内涵段子抓取类

class neiHanSpider :

def __init__(self):

self.primer_url = 'http://neihanshequ.com/pic/'

#点击加载更多之后请求的url

self.base_url = 'http://neihanshequ.com/pic/?is_json=1&max_time='

def Start(self):

#首先获取第一个页面的html数据,并分析其中的data-pic和max_time

primer_html = self.__getHtml(self.primer_url)

data_pic = self.__getDataPic(primer_html)

max_time = self.__getMaxTime(primer_html)

#download pic

self.__downloadPic(data_pic)

count = 0

#下面开始下载点击更多之后的图片

while max_time:

count = count + 1

print "=--------------------THIS IS THE " + str(count) + " Json Data Time : " + str(max_time) + "--------------------"

url = self.base_url + str(max_time)

json_data = self.__getHtml(url)

json_ret = self.__parseJson(json_data)

max_time = json_ret['max_time']

print max_time

image_url = json_ret['image_url']

image_content = json_ret['image_content']

self.__downloadPic(image_url,image_content)

#python 以两个下划线开始的为私有函数

#尝试5次

#解析json,并获取json中的数据

def __parseJson(self,json_data):

print "------This is parse_json --------"

dct = json.loads(json_data)

image_content = []

image_url = []

max_time = ""

try :

max_time = dct['data']['max_time']

data = dct['data']['data']

for item in data:

content = item['group']['content']

url = item['group']['large_image']['url_list'][0]['url']

image_content.append(content)

image_url.append(url)

ret = {}

ret['image_content'] = image_content

ret['image_url'] = image_url

ret['max_time'] = max_time

return ret

except :

print "json_parse error"

#定义下载图片函数

def __downloadPic(self,imageAddressList,contentList = []):

print "---download------"

contentExist = len(contentList)

count = 0

for image in imageAddressList :

print image

count = count + 1

randTail = str(random.randint(0,30000000))

try :

#tail = contentExist ? contentList[count - 1] : randTail ;

if contentExist :

tail = contentList[count - 1]

else :

tail = randTail

fullPath = "C:\\Users\\Administrator\\Desktop\\python\\" + tail + ".jpg"

urllib.urlretrieve(image , fullPath)

except :

failedMsg = "第" + str(count) + "张下载失败,URL: " + str(image) + ""

print failedMsg

pass

def __getDataPic(self,html):

re_str = r'data-pic="([^"]*)"'

data_pic = self.__getDataByRe(html,re_str)

return data_pic

def __getMaxTime(self,html):

re_str = r'max_time: \'([\d]*)\''

max_time = self.__getDataByRe(html,re_str)

return max_time

def __getDataByRe(self,text,re_str):

pattern = re.compile(re_str)

ret = pattern.findall(text)

return ret

def __getHtml(self,url):

print "GET HTML********"

count = 0

while count < 5:

count = count + 1

print str(count) + " times ,try download html"

html = self.__getDataByUrl(url)

if not html:

continue;

else:

return html

def __getDataByUrl(self,url):

print "---------------now get html from url :" + url + "----------"

send_headers = {

&#39;Host&#39;:&#39;neihanshequ.com&#39;,

&#39;User-Agent&#39;:&#39;Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0&#39;,

&#39;Cookie&#39;:"pksrqup=1; csrftoken=237f4451075fe45cef3a4f5449f70658; tt_webid=3379513254; uuid=\"w:33266c46f0cc4fa6944c073b1b1bccea\"",

&#39;Connection&#39;:&#39;keep-alive&#39;

}

req = urllib2.Request(url ,headers=send_headers)

try:

response = urllib2.urlopen(req ,timeout = 100)

html = response.read()

return html

except urllib2.HTTPError, e:

print &#39;The server couldn\&#39;t fulfill the request.&#39;

print &#39;Error code: &#39;, e.code

except urllib2.URLError, e:

print &#39;We failed to reach a server.&#39;

print &#39;Reason: &#39;, e.reason

else:

print &#39;No exception was raised.&#39;

#------------------------------------------程序入口处------------------------------

mySpider = neiHanSpider()

mySpider.Start()

  之后我再次尝试了多线程版本

  # -*- coding: utf-8 -*-

import urllib2

import urllib

import re

import threading

import time

import os

import random

import json

#内涵段子抓取类

class neiHanSpider :

def __init__(self ):

self.primer_url = &#39;http://neihanshequ.com/pic/&#39;

#点击加载更多之后请求的url

self.base_url = &#39;http://neihanshequ.com/pic/?is_json=1&max_time=&#39;

def Start(self):

#首先获取第一个页面的html数据,并分析其中的data-pic和max_time

primer_html = self.__getHtml(self.primer_url)

data_pic = self.__getDataPic(primer_html)

max_time = self.__getMaxTime(primer_html)

#download pic

#self.__downloadPic(data_pic)

global downloadUrlList

global downloadTitleList

#downloadList = downloadList + data_pic

count = 0

#下面开始下载点击更多之后的图片

while max_time and count " + str(len(downloadTitleList))

threadLock = threading.Lock()

threads = []

size = len(downloadUrlList)

for i in range(1,10) :

thread = myDownLoad(i,"Thread-" + str(i));

thread.start()

threads.append(thread)

aliveCount = 10

while aliveCount > 1 :

print "Now There is " + str(aliveCount) + "Threads alive"

aliveCount = threading.activeCount()

time.sleep(10)

endTime = time.time()

print " Download " + str(size) + "张图,共耗时 " + str((endTime - startTime) / 60) + "min"

print "Exiting Main Thread"

  可能写的不是很整齐,有时间再整理一下。Python现正在使用中,欢迎批评指正

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线