python爬取网页表格3 怎样爬取动态加载的网页信息

用python编写递归爬取多重网址的网站信息 - 太阳风 - ITeye博客
博客分类:
&& 项目组要得到这个http://kalug.linux.org.tw/~shawn/project/thesis/目录网址下面的所有文件以及这个文件目录的下层目录以及更下层目录的文件包括这个,用迅雷,flashget好像都没这样的功能:找到给一个链接,然后再递归爬取这个链接下的所有链接的。
&& 于是自己写了一个,好像还行o(∩_∩)o...呵呵 下面是代码,这里主要爬取pdf与doc文件。
# -*- coding: utf-8 -*-
import urlparse,urllib,re,os
this class is mainly used to crawl the deep url in the urls
do this work for 242
class SpiderMulti:
def read(self,url):
urlli=self.analy(url)
urldic = {}
cutli=urlli[1:]
for x in cutli:
urldic.update(x)
for url in [x.keys()[0] for x in cutli]:
if self.islink(url,urldic):
self.read(url)
self.download(url,urldic)
def analy(self,url):
html=urllib.urlopen(url).read().split('\n')
orignalUrl = url
#re.search(r'&h2&(.*?)&/h2&',url,re.I|re.DOTALL)
for eachline in html:
#print eachline
currentFind = re.search(r'href="(.*?)"',eachline,re.IGNORECASE|re.DOTALL)
if currentFind:
urldic = {}
curUrl = urlparse.urljoin(orignalUrl,currentFind.group(1))
dirFind = re.search(r'class="t".*?&(.*?)&',eachline,re.IGNORECASE|re.DOTALL)
curDir = dirFind.group(1)
urldic[curUrl]=curDir
urlli.append(urldic)
print 'can not open ',url
#print urlli
return urlli
def islink(self,url,urldic):
if urldic[url] == 'Directory':
return True
return False
def download(self,url,urldic):
print '=====:',url,urldic[url]
if (self.isfile(url)):
name = os.path.join(r'd:\data',url.split('/')[-1])
print 'dowm:',url,name
f=urllib.urlretrieve(url,name)
print 'can not writtofile'
def isfile(self,url):
if re.search(r'doc$|pdf$',url,re.IGNORECASE|re.DOTALL):
return True
return False
if __name__=='__main__':
t=SpiderMulti()
url='http://kalug.linux.org.tw/~shawn/project/thesis/'
t.read(url)
解释一下:
1、主函数是read(),在这里面实现递归。
2、analy(url)函数分析传入的url,提取出该页的url链接,当然如果你要用你自己的url这里需要改变的是正则表达式的匹配规则。返回一个列表,列表的元素是字典,key是当前的链接地址,值是该地址对应的类型(这里主要是针对该类网站这样设计的,大家可以打开看看网页
的结果)。
3、islink()函数是判断输入的url是不是目录,如果是则递归执行read()函数
4、download()函数是:输入的链接对应的是个文件,但是不一定是我们想要的pdg或者doc文件,所以先用isfile()函数判断一下,然后再进行下载,完成任务。呵呵
浏览: 52022 次
来自: 杭州
楼主好认真, 好可爱....可是不是没有坚持下去?
http://ajava.org
这个非常不错!
鹤惊昆仑 写道vim列选择(可视)模式比较适合解决这个吧?恩, ...
vim列选择(可视)模式比较适合解决这个吧?
tuoxie007 写道du -h 一下不就行了吗也用过du教你用python3根据关键词爬取百度百科的内容_python
关于python版本,我一开始看很多资料说python2比较好,因为很多库还不支持3,但是使用到现在为止觉得还是pythin3比较好用,因为编码什么的问题,觉得2还是没有3方便。而且在网上找到的2中的一些资料稍微改一下也还是可以用。
好了,开始说爬百度百科的事。
这里设定的需求是爬取北京地区n个景点的全部信息,n个景点的名称是在文件中给出的。没有用到api,只是单纯的爬网页信息。
1、根据关键字获取url
由于只需要爬取信息,而且不涉及交互,可以使用简单的方法而不需要模拟浏览器。
&strong&/search/word?word="guanjianci"&/strong&
&strong&for &/strong&l &strong&in &/strong&view_names:
&strong&'''/search/word?word=''' &/strong&&em&# 得到url的方法
&/em&&em& &/em&name=urllib.parse.quote(l)
name.encode(&strong&'utf-8'&/strong&)
url=&strong&'/search/word?word='&/strong&+name
这里要注意关键词是中午所以要注意编码问题,由于url中不能出现空格,所以需要用quote函数处理一下。
关于quote():
在 Python2.x 中的用法是:urllib.quote(text)
。Python3.x 中是urllib.parse.quote(text)
。按照标准,URL只允许一部分ASCII 字符(数字字母和部分符号),其他的字符(如汉字)是不符合URL标准的。所以URL中使用其他字符就需要进行URL编码。URL中传参数的部分(query String),格式是:name1=value1&name2=value2&name3=value3。假如你的name或者value值中的『&』或者『=』等符号,就当然会有问题。所以URL中的参数字符串也需要把『&=』等符号进行编码。URL编码的方式是把需要编码的字符转化为%xx的形式。通常URL编码是基于UTF-8的(当然这和浏览器平台有关)
比如『我,unicode 为 0x6211,UTF-8编码为0xE60x880x91,URL编码就是 %E6%88%91。
Python的urllib库中提供了quote和quote_plus两种方法。这两种方法的编码范围不同。不过不用深究,这里用quote就够了。
2、下载url
用urllib库轻松实现,见下面的代码中def download(self,url)
3、利用Beautifulsoup获取html
4、数据分析
百科中的内容是并列的段,所以在爬的时候不能自然的按段逻辑存储(因为全都是并列的)。所以必须用正则的方法。
基本的想法就是把整个html文件看做是str,然后用正则的方法截取想要的内容,在重新把这段内容转换成beautifulsoup对象,然后在进一步处理。
可能要花些时间看一下正则。
代码中还有很多细节,忘了再查吧只能,下次绝对应该边做编写,或者做完马上写。。。
# coding:utf-8
function:爬取百度百科所有北京景点,
import urllib.request
from urllib.request import urlopen
from urllib.error import HTTPError
import urllib.parse
from bs4 import BeautifulSoup
import codecs
import json
class BaikeCraw(object):
def __init__(self):
self.urls =set()
self.view_datas= {}
def craw(self,filename):
urls = self.getUrls(filename)
if urls == None:
print("not found")
for urll in urls:
print(urll)
html_count=self.download(urll)
self.passer(urll, html_count)
print("view do not exist")
'''file=self.view_datas["view_name"]
self.craw_pic(urll,file,html_count)
print(file)'''
def getUrls (self, filename):
new_urls = set()
file_object = codecs.open(filename, encoding='utf-16', )
all_text = file_object.read()
print("文件打开异常!")
file_object.close()
file_object.close()
view_names=all_text.split(" ")
for l in view_names:
if '?' in l:
view_names.remove(l)
for l in view_names:
'''/search/word?word=''' # 得到url的方法
name=urllib.parse.quote(l)
name.encode('utf-8')
url='/search/word?word='+name
new_urls.add(url)
print(new_urls)
return new_urls
def manger(self):
def passer(self,urll,html_count):
soup = BeautifulSoup(html_count, 'html.parser', from_encoding='utf_8')
self._get_new_data(urll, soup)
def download(self,url):
if url is None:
return None
response = urllib.request.urlopen(url)
if response.getcode() != 200:
return None
return response.read()
def _get_new_data(self, url, soup): ##得到数据
if soup.find('div',class_="main-content").find('h1') is not None:
self.view_datas["view_name"]=soup.find('div',class_="main-content").find('h1').get_text()#景点名
print(self.view_datas["view_name"])
self.view_datas["view_name"] = soup.find("div", class_="feature_poster").find("h1").get_text()
self.view_datas["view_message"] = soup.find('div', class_="lemma-summary").get_text()#简介
self.view_datas["basic_message"]=soup.find('div', class_="basic-info cmn-clearfix").get_text() #基本信息
self.view_datas["basic_message"]=self.view_datas["basic_message"].split("\n")
for line in self.view_datas["basic_message"]:
if line != "":
get.append(line)
self.view_datas["basic_message"]=get
for line in self.view_datas["basic_message"]:
if i % 2 == 1:
a=tmp+":"+line
get2.append(a)
self.view_datas["basic_message"] = get2
self.view_datas["catalog"] = soup.find('div', class_="lemma-catalog").get_text().split("\n")#目录整体
for line in self.view_datas["catalog"]:
if line != "":
get.append(line)
self.view_datas["catalog"] = get
#########################百科内容
view_name=self.view_datas["view_name"]
html = urllib.request.urlopen(url)
soup2 = BeautifulSoup(html.read(), 'html.parser').decode('utf-8')
p = re.compile(r'', re.DOTALL) # 尾
r = p.search(content_data_node)
content_data = content_data_node[0:r.span(0)[0]]
lists = content_data.split('')
for list in lists:#每一大块
final_soup = BeautifulSoup(list, "html.parser")
name_list = None
part_name = final_soup.find('h2', class_="title-text").get_text().replace(view_name, '').strip()
part_data = final_soup.get_text().replace(view_name, '').replace(part_name, '').replace('编辑', '') # 历史沿革
name_list = final_soup.findAll('h3', class_="title-text")
all_name_list = {}
na="part_name"+str(i)
all_name_list[na] = part_name
final_name_list = []###########
for nlist in name_list:
nlist = nlist.get_text().replace(view_name, '').strip()
final_name_list.append(nlist)
fin="final_name_list"+str(i)
all_name_list[fin] = final_name_list
print(all_name_list)
p = re.compile(r'', re.DOTALL)
final_soup = final_soup.decode('utf-8')
r = p.search(final_soup)
final_part_data = final_soup[r.span(0)[0]:]
part_lists = final_part_data.split('')
for part_list in part_lists:
final_part_soup = BeautifulSoup(part_list, "html.parser")
content_lists = final_part_soup.findAll("div", class_="para")
for content_list in content_lists: # 每个最小段
pic_word = content_list.find("div",
class_="lemma-picture text-pic layout-right").get_text() # 去掉文字中的图片描述
pic_word2 = content_list.find("div", class_="description").get_text() # 去掉文字中的图片描述
content_list = content_list.get_text().replace(pic_word, '').replace(pic_word2, '')
content_list = content_list.get_text().replace(pic_word, '')
pic_word2 = content_list.find("div", class_="description").get_text() # 去掉文字中的图片描述
content_list = content_list.get_text().replace(pic_word2, '')
content_list = content_list.get_text()
r_part = re.compile(r'\[\d.\]|\[\d\]')
part_result, number = re.subn(r_part, "", content_list)
part_result = "".join(part_result.split())
#print(part_result)
final_part_soup = BeautifulSoup(list, "html.parser")
content_lists = final_part_soup.findAll("div", class_="para")
for content_list in content_lists:
pic_word = content_list.find("div", class_="lemma-picture text-pic layout-right").get_text() # 去掉文字中的图片描述
pic_word2 = content_list.find("div", class_="description").get_text() # 去掉文字中的图片描述
content_list = content_list.get_text().replace(pic_word, '').replace(pic_word2, '')
content_list = content_list.get_text().replace(pic_word, '')
pic_word2 = content_list.find("div", class_="description").get_text() # 去掉文字中的图片描述
content_list = content_list.get_text().replace(pic_word2, '')
content_list = content_list.get_text()
r_part = re.compile(r'\[\d.\]|\[\d\]')
part_result, number = re.subn(r_part, "", content_list)
part_result = "".join(part_result.split())
#print(part_result)
print("error")
def output(self,filename):
json_data = json.dumps(self.view_datas, ensure_ascii=False, indent=2)
fout = codecs.open(filename+'.json', 'a', encoding='utf-16', )
fout.write( json_data)
# print(json_data)
def craw_pic(self,url,filename,html_count):
soup = BeautifulSoup(html_count, 'html.parser', from_encoding='utf_8')
node_pic=soup.find('div',class_='banner').find("a", pile("/photo/poi/....\."))
if node_pic is None:
return None
part_url_pic=node_pic['href']
full_url_pic=urllib.parse.urljoin(url,part_url_pic)
#print(full_url_pic)
html_pic = urlopen(full_url_pic)
except HTTPError as e:
return None
soup_pic=BeautifulSoup(html_pic.read())
pic_node=soup_pic.find('div',class_="album-list")
print(pic_node)
if __name__ =="__main__" :
spider=BaikeCraw()
filename="D:\PyCharm\\view_spider\\view_points_part.txt"
spider.craw(filename)
用python3根据关键词爬取百度百科的内容到这就基本结束了,希望这篇能对大家学习python有所帮助。python3 爬虫日记(三) 爬取堆糖动态加载网页 - Mliangydy的博客 - CSDN博客
python3 爬虫日记(三) 爬取堆糖动态加载网页
1.分析:进入堆糖网后我们在分类找到插画绘画进入这个分类后发现好多图片,下拉后发现会有不断的图片刷新出来,这就是堆糖采用了动态加载网页。
2.用开发者工具(F12)分析:按一下F12,找到network分支,再按一下F5,将刷新后的网页一直往下拉,打开XHR,发现Name下有两个或多个?include开头字段,然后观察Header和Preview发现它的图片信息是json格式的数据。
3.准备开工。
# -*- coding:utf-8 -*-
import pymongo
from requests.exceptions import RequestException
import requests
import json
from urllib.parse import urlencode
def get_index_page(start_page,id_page):
headers = {
'User-Agent': &Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3&,
'Referer':'/category/?cat=painting',
'Accept': 'text/plain, */*; q=0.01',
'Host': '',
'Accept - Encoding': 'gzip,deflate, sdch',
'Accept - Language': 'zh - CN,q=0.8',
'Connection': 'keep - alive',
'include_fields': 'top_comments,'
'is_root, source_link, item, buyable, root_id, status, like_count, sender, album',
'filter_id': '插画绘画',
'start':start_page,
'_':id_page,
url = '/napi/blog/list/by_filter_id/?' + urlencode(data) # 拼接URL
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.text
return None
except RequestException:
print('请求索引页出错!')
return None
def parse_page_index():
while i & 23976:
i = i + 24
html = get_index_page(i, n)
for n in range(24):
data = json.loads(html.strip())
# 将json字典转换为python字典
img_url = data['data']['object_list'][n]['photo']['path'] # 获取字典中的图片链接
title = data['data']['object_list'][n]['msg']
# 获取字典中的标题
post_sub.insert_one({'img_id': title, 'img_url': img_url}) # 插入到数据库中
print(title,img_url)
if __name__ == '__main__':
connection = pymongo.MongoClient()
post_info = connection.duitang_painting
post_sub = post_info.duitang
parse_page_index()
我的热门文章
即使是一小步也想与你分享爬虫,如何获取动态页面 - CNode技术社区
这个家伙很懒,没有留下个性签名
刚开始做爬虫,在爬一个动态页面的时候如果一下子返回content,是空字符串
怎么等待它页面绘制完成呢,新手
等待绘制完成 可以试试用 PhantomJS 或者 node-webkit来弄
还有一种思路是直接找到对应的数据接口,取代爬网页
如果状态码是200,内容是空,那个页面就是个空页面
如果302重定向,那么直接请求跳转指向的地址
如果ajax加载,那还是得找接口地址
普通爬虫应该用不上node-webkit
动态页面是指html由服务器动态生成,还是网页内容由javascript控制动态生成?
应该是javascript
如果是像 angularjs 之类,内容由浏览器的 js 生成,推荐 PhantomJS
是的。它页面里的东西都是angularjs 的{{}}绑定,而且都以GB2312编码,Windows下也不能用那个iconv解码,晕了
现在只有通过phantomJS来实现了.我原来试过用selenium,它的开销更大.
我记得 iconv-lite在win下面是可以用的。如果你是针对特定具体网站进行抓取,那还是用request库好些,开销小速度快。
来自酷炫的
你有没试过splash。
开发者是开发来配合scrapy用的,但只是个渲染代理。
爬虫还是python各种东西全,更何况现在python都有async关键字了。。。
恩,inconv-lite可以用,但是不能处理宽字节,iconv不能用
动态页面不能爬网址,建议你找一下人家的接口,我就是那么爬得。
可以试试用cheerio.load() 如果不行就老老实实按F12看timeline找对应数据接口吧
那不能啊?怎么说不能处理的,举个实例?
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的

我要回帖

更多关于 python爬取动态网页 的文章

 

随机推荐