python爬虫抓取图片机票信息

问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
项目组为了能预测今后各航线的价格变化情况,在收集以前机票价格信息的同时,也希望能采集到现在的机票情况,看到去哪儿网站也是通过搜索其它网站得到数据的:
不知道如何像去哪儿那样抓取各网站的机票信息,当然如果能直接利用网络爬虫抓取到“去哪儿”搜索页面的信息当然最好。
望各位帮我出出主意!
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
我这里是用火车头
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
在对方没有相应API使用的话,爬虫是最简单直接的办法。
python的爬虫也比较简单,很早学python的时候写过一篇爬虫的,可以参考
同步到新浪微博
分享到微博?
你好!看起来你挺喜欢这个内容,但是你还没有注册帐号。 当你创建了帐号,我们能准确地追踪你关注的问题,在有新答案或内容的时候收到网页和邮件通知。还能直接向作者咨询更多细节。如果上面的内容有帮助,记得点赞 (????)? 表示感谢。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
最近在学习selenium,遇到一个很奇怪的问题,debug了半天还是没弄明白,我是在测试抓取携程网站的机票信息
我的代码:
# -*- coding: utf-8 -*-
from selenium import webdriver
import time
from lxml import etree
#在订票页面/
driver = webdriver.Chrome()
driver.get('/')
time.sleep(1)
element_time = driver.find_element_by_id('DepartDate1TextBox')
element_time.send_keys(u'')
element_arr = driver.find_element_by_id('ArriveCity1TextBox')
element_arr.send_keys(u'北京')
element_depart = driver.find_element_by_id('DepartCity1TextBox')
element_depart.send_keys(u'南京')
driver.find_element_by_id('search_btn').click()
#点击click事件后,页面其实是跳转到/domestic/Search/FirstRoute/?DCity1=NKG&ACity1=BJS&DDate1=
time.sleep(1)
print driver.current_url
#点击重新搜索
driver.find_element_by_id('btnReSearch').click()
print driver.current_url
for i in range(3):
js = 'window.scrollTo(0,100000)'
time.sleep(1)
driver.execute_script(js)
time.sleep(1)
html_text = driver.page_source
selector = etree.HTML(html_text)
outer_div = selector.xpath('//div[@class="search_box
search_box_tag
driver.quit()
print outer_div
然后就是我对这小块代码的调试时发现得到的结果是一致的,但是,但是,当我再次debug时,或者运行时发现取不到数据,经过很多次测试,发现一半时候取到,一半时候取不到,后面我去掉driver.quit()调试发现同样的url,但是div出现2个不一样的,导致抓取不到,所以我很奇怪为什么会出现这种问题
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
使用selector.xpath('//div[contains(@class,"search_box
search_box_tag")]')试试?
同步到新浪微博
分享到微博?
你好!看起来你挺喜欢这个内容,但是你还没有注册帐号。 当你创建了帐号,我们能准确地追踪你关注的问题,在有新答案或内容的时候收到网页和邮件通知。还能直接向作者咨询更多细节。如果上面的内容有帮助,记得点赞 (????)? 表示感谢。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:本栏最新文章
限制 已用 剩余&Python爬虫-抓取手机APP数据 - 开源中国社区
当前访客身份:游客 [
当前位置:
发布于 日 16时,
抓取超级课程表话题数据。博文:http://my.oschina.net/jhao104/blog/606922
代码片段(1)
1.&[代码]代码&&&&
#!/usr/local/bin/python2.7
# -*- coding: utf8 -*-
超级课程表话题抓取
import urllib2
from cookielib import CookieJar
import json
''' 读Json数据 '''
def fetch_data(json_data):
data = json_data['data']
timestampLong = data['timestampLong']
messageBO = data['messageBOs']
topicList = []
for each in messageBO:
topicDict = {}
if each.get('content', False):
topicDict['content'] = each['content']
topicDict['schoolName'] = each['schoolName']
topicDict['messageId'] = each['messageId']
topicDict['gender'] = each['studentBO']['gender']
topicDict['time'] = each['issueTime']
print each['schoolName'],each['content']
topicList.append(topicDict)
return timestampLong, topicList
''' 加载更多 '''
def load(timestamp, headers, url):
headers['Content-Length'] = '159'
loadData = 'timestamp=%s&phoneBrand=Meizu&platform=1&genderType=-1&topicId=19&phoneVersion=16&selectType=3&channel=MXMarket&phoneModel=M040&versionNumber=7.2.1&' % timestamp
req = urllib2.Request(url, loadData, headers)
loadResult = opener.open(req).read()
loginStatus = json.loads(loadResult).get('status', False)
if loginStatus == 1:
print 'load successful!'
timestamp, topicList = fetch_data(json.loads(loadResult))
load(timestamp, headers, url)
print 'load fail'
print loadResult
return False
loginUrl = 'http://120.55.151.61/V2/StudentSkip/loginCheckV4.action'
topicUrl = 'http://120.55.151.61/V2/Treehole/Message/getMessageByTopicIdV3.action'
headers = {
'Content-Type': 'application/x-www-form- charset=UTF-8',
'User-Agent': 'Dalvik/1.6.0 (L U; Android 4.1.1; M040 Build/JRO03H)',
'Host': '120.55.151.61',
'Connection': 'Keep-Alive',
'Accept-Encoding': 'gzip',
'Content-Length': '207',
''' ---登录部分--- '''
loginData = 'phoneBrand=Meizu&platform=1&deviceCode=494&account=FCF030E1F2FBE5BBC422A3D&phoneVersion=16&password=A55B48BB75CA18C5F47D6&channel=MXMarket&phoneModel=M040&versionNumber=7.2.1&'
cookieJar = CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookieJar))
req = urllib2.Request(loginUrl, loginData, headers)
loginResult = opener.open(req).read()
loginStatus = json.loads(loginResult).get('data', False)
if loginResult:
print 'login successful!'
print 'login fail'
print loginResult
''' ---获取话题--- '''
topicData = 'timestamp=0&phoneBrand=Meizu&platform=1&genderType=-1&topicId=19&phoneVersion=16&selectType=3&channel=MXMarket&phoneModel=M040&versionNumber=7.2.1&'
headers['Content-Length'] = '147'
topicRequest = urllib2.Request(topicUrl, topicData, headers)
topicHtml = opener.open(topicRequest).read()
topicJson = json.loads(topicHtml)
topicStatus = topicJson.get('status', False)
print topicJson
if topicStatus == 1:
print 'fetch topic success!'
timestamp, topicList = fetch_data(topicJson)
data = load(timestamp, headers, topicUrl)
timestamp, topicList = fetch_data(data)
开源中国-程序员在线工具:
相关的代码(157)
2回/1264阅
0回/1344阅
开源从代码分享开始
j_hao104的其它代码Python爬虫爬取知乎小结
最近学习了一点网络爬虫,并实现了使用python来爬取知乎的一些功能,这里做一个小的总结。网络爬虫是指通过一定的规则自动的从网上抓取一些信息的程序或脚本。我们知道机器学习和数据挖掘等都是从大量的数据出发,找到一些有价值有规律的东西,而爬虫则可以帮助我们解决获取数据难的问题,因此网络爬虫是我们应该掌握的一个技巧。
python有很多开源工具包供我们使用,我这里使用了requests、BeautifulSoup4、json等包。requests模块帮助我们实现http请求,bs4模块和json模块帮助我们从获取到的数据中提取一些想要的信息,几个模块的具体功能这里不具体展开。下面我分功能来介绍如何爬取知乎。
要想实现对知乎的爬取,首先我们要实现模拟登录,因为不登录的话好多信息我们都无法访问。下面是登录函数,这里我直接使用了知乎用户的登录函数,具体如下。其中你要在函数中的data里填上你的登录账号和密码,然后在爬虫之前先执行这个函数,不出意外的话你就登录成功了,这时你就可以继续抓取想要 的数据。注意,在首次使用该函数时,程序会要求你手动输入captcha码,输入之后当前文件夹会多出cookiefile文件和zhihucaptcha.gif,前者保留了cookie信息,后者则保存了验证码,之后再去模拟登录时,程序会自动帮我们填上验证码。
def login():
url = ''
loginURL = '/login/email'
headers = {
&User-Agent&: 'Mozilla/5.0 (M Intel Mac OS X 10.10; rv:41.0) Gecko/ Firefox/41.0',
&Referer&: &/&,
'Host': '',
'email': '',
'password': '**************',
'rememberme': &true&,
s = requests.session()
global xsrf
if os.path.exists('cookiefile'):
with open('cookiefile') as f:
cookie = json.load(f)
s.cookies.update(cookie)
req1 = s.get(url, headers=headers)
soup = BeautifulSoup(req1.text, &html.parser&)
xsrf = soup.find('input', {'name': '_xsrf', 'type': 'hidden'}).get('value')
# 建立一个zhihu.html文件,用于验证是否登陆成功
with open('zhihu.html', 'w') as f:
f.write(req1.content)
req = s.get(url, headers=headers)
soup = BeautifulSoup(req.text, &html.parser&)
xsrf = soup.find('input', {'name': '_xsrf', 'type': 'hidden'}).get('value')
data['_xsrf'] = xsrf
timestamp = int(time.time() * 1000)
captchaURL = '/captcha.gif?=' + str(timestamp)
print captchaURL
with open('zhihucaptcha.gif', 'wb') as f:
captchaREQ = s.get(captchaURL, headers=headers)
f.write(captchaREQ.content)
loginCaptcha = raw_input('input captcha:\n').strip()
data['captcha'] = loginCaptcha
print data
loginREQ = s.post(loginURL, headers=headers, data=data)
if not loginREQ.json()['r']:
print s.cookies.get_dict()
with open('cookiefile', 'wb') as f:
json.dump(s.cookies.get_dict(), f)
print 'login fail'
需要注意的是,在login函数中有一个全局变量s=reequests.session(),我们用这个全局变量来访问知乎,整个爬取过程中,该对象都会保持我们的持续模拟登录。
获取用户基本信息
知乎上每个用户都有一个唯一ID,例如我的ID是marcovaldong,那么我们就可以通过访问地址
来访问我的主页。个人主页中包含了居住地、所在行业、性别、教育情况、获得的赞数、感谢数、关注了哪些人、被哪些人关注等信息。因此,我首先介绍如何通过爬虫来获取某一个知乎用户的一些信息。下面的函数get_userInfo(userID)实现了爬取一个知乎用户的个人信息,我们传递给该用户一个用户ID,该函数就会返回一个 list,其中包含昵称、ID、居住地、所在行业、性别、所在公司、职位、毕业学校、专业、赞同数、感谢数、提问数、回答数、文章数、收藏数、公共编辑数量、关注的人数、被关注的人数、主页被多少个人浏览过等19个数据。
def get_userInfo(userID):
user_url = '/people/' + userID
response = s.get(user_url, headers=header_info)
# print response
soup = BeautifulSoup(response.content, 'lxml')
name = soup.find_all('span', {'class': 'name'})[1].string
# print 'name: %s' % name
ID = userID
# print 'ID: %s' % ID
location = soup.find('span', {'class': 'location item'})
if location == None:
location = 'None'
location = location.string
# print 'location: %s' % location
business = soup.find('span', {'class': 'business item'})
if business == None:
business = 'None'
business = business.string
# print 'business: %s' % business
gender = soup.find('input', {'checked': 'checked'})
if gender == None:
gender = 'None'
gender = gender['class'][0]
# print 'gender: %s' % gender
employment = soup.find('span', {'class': 'employment item'})
if employment == None:
employment = 'None'
employment = employment.string
# print 'employment: %s' % employment
position = soup.find('span', {'class': 'position item'})
if position == None:
position = 'None'
position = position.string
# print 'position: %s' % position
education = soup.find('span', {'class': 'education item'})
if education == None:
education = 'None'
education = education.string
# print 'education: %s' % education
major = soup.find('span', {'class': 'education-extra item'})
if major == None:
major = 'None'
major = major.string
# print 'major: %s' % major
agree = int(soup.find('span', {'class': 'zm-profile-header-user-agree'}).strong.string)
# print 'agree: %d' % agree
thanks = int(soup.find('span', {'class': 'zm-profile-header-user-thanks'}).strong.string)
# print 'thanks: %d' % thanks
infolist = soup.find_all('a', {'class': 'item'})
asks = int(infolist[1].span.string)
# print 'asks: %d' % asks
answers = int(infolist[2].span.string)
# print 'answers: %d' % answers
posts = int(infolist[3].span.string)
# print 'posts: %d' % posts
collections = int(infolist[4].span.string)
# print 'collections: %d' % collections
logs = int(infolist[5].span.string)
# print 'logs: %d' % logs
followees = int(infolist[len(infolist)-2].strong.string)
# print 'followees: %d' % followees
followers = int(infolist[len(infolist)-1].strong.string)
# print 'followers: %d' % followers
scantime = int(soup.find_all('span', {'class': 'zg-gray-normal'})[len(soup.find_all('span', {'class': 'zg-gray-normal'}))-1].strong.string)
# print 'scantime: %d' % scantime
info = (name, ID, location, business, gender, employment, position,
education, major, agree, thanks, asks, answers, posts,
collections, logs, followees, followers, scantime)
return info
if __name__ == '__main__':
userID = 'marcovaldong'
info = get_userInfo(userID)
print 'The information of ' + userID + ' is: '
for i in range(len(info)):
print info[i]
下图是我的主页的部分截图,从上面可以看到这19个数据,下面第二张图是终端上显示的我的这19个数据,我们可以作个对照,看看是否全部抓取到了。这个函数我用了很长时间来调试,因为不同人的主页的信息完整程度是不同的,如果你在使用过程中发现了错误,欢迎告诉我。
获取某个答案的所有点赞者名单
知乎上有一个问题是,我参考了的这个答案爬虫,然后有了下面的这个函数。
这里先来大概的分析一下整个流程。我们要知道,知乎上的每一个问题都有一个唯一ID,这个可以从地址中看出来,例如问题的地址为
,其中就是其ID。而每一个问题下的每一个答案也有一个唯一ID,例如该问题下的最高票答案的地址链接为
,末尾的就是该答案在该问题下的唯一ID。不过我们这里用到的不是这两个ID,而是我们在抓取点赞者名单时的唯一ID,此ID的获得方法是这样:例如我们打算抓取的点赞者名单,首先打开firebug,点击&5321 人赞同&时,firebug会抓取到一个&GET voters_profile&的一个包,把光标放在上面,会看到一个链接
,其中的5430533才是我们在抓取点赞者名单时用到的一个唯一ID。注意此ID只有在答案被赞过后才有。(在这安利一下《人间正道是沧桑》这部电视剧,该剧以杨立青三兄妹的恩怨情仇为线索,从大革命时期到解放战争,比较全面客观的展现了国共两党之间的主义之争,每一次看都会新的认识和体会。)
在拿到唯一ID后,我们用requests模块去get到知乎返回的信息,其中有一个json语句,该json语句中包含点赞者的信息。另外,我们在网页上浏览点赞者名单时,一次只能看到20条,每次下拉到名单底部时又加载出20条信息,再加载20条信息时所用的请求地址也包含在前面的json语句中。因此我们需要从json语句中提取出点攒着信息和下一个请求地址。在网页上浏览点赞者名单时,我们可以看到点赞者的昵称、头像、获得了多少赞同和感谢,以及提问和回答的问题数量,这里我提取了每个点赞者的昵称、主页地址(也就是用户ID)、赞同数、感谢数、提问数和回答数。关于头像的提取,我会在下面的函数中实现。
在提取到点赞者名单后,我将者信息保存了以唯一ID命名的txt文件中。下面是函数的具体实现。
Zhihu = ''
def get_voters(ans_id):
# 直接输入问题id(这个id在点击&等人赞同&时可以通过监听网络得到),关注者保存在以问题id命名的.txt文件中
file_name = str(ans_id) + '.txt'
f = open(file_name, 'w')
source_url = Zhihu + '/answer/' +str(ans_id) +'/voters_profile'
source = s.get(source_url, headers=header_info)
print source
content = source.content
print content
# json语句
data = json.loads(content)
# 包含总赞数、一组点赞者的信息、指向下一组点赞者的资源等的数据
# 打印总赞数
txt1 = '总赞数'
print txt1.decode('utf-8')
total = data['paging']['total']
print data['paging']['total']
# 通过分析,每一组资源包含10个点赞者的信息(当然,最后一组可能少于10个),所以需要循环遍历
nextsource_url = source_url
# 从第0组点赞者开始解析
while nextsource_url!=Zhihu:
nextsource = s.get(nextsource_url, headers=header_info)
time.sleep(2)
nextsource = s.get(nextsource_url, headers=header_info)
# 解析出点赞者的信息
nextcontent = nextsource.content
nextdata = json.loads(nextcontent)
# 打印每个点赞者的信息
# txt2 = '打印每个点赞者的信息'
# print txt2.decode('utf-8')
# 提取每个点赞者的基本信息
for each in nextdata['payload']:
soup = BeautifulSoup(each, 'lxml')
tag = soup.a
title = tag['title']
# 点赞者的用户名
href = '' + str(tag['href'])
# 点赞者的地址
# 获取点赞者的数据
list = soup.find_all('li')
votes = list[0].string
# 点赞者获取的赞同
tks = list[1].string
# 点赞者获取的感谢
ques = list[2].string
# 点赞者提出的问题数量
ans = list[3].string
# 点赞者回答的问题数量
# 打印点赞者信息
string = title + '
' + href + '
' + votes + tks + ques + ans
f.write(string + '\n')
print string
txt3 = '有点赞者的信息缺失'
f.write(txt3.decode('utf-8') + '\n')
print txt3.decode('utf-8')
# 解析出指向下一组点赞者的资源
nextsource_url = Zhihu + nextdata['paging']['next']
注意,点赞者名单中会有匿名用户,或者有用户被注销,这时我们抓取不到此用户的信息,我这里在txt文件中添加了一句&有点赞者的信息缺失&。
使用同样的方法,我们就可以抓取到一个用户的关注者名单和被关注者名单,下面列出了这两个函数。但是关注者名单抓取函数有一个问题,每次使用其抓取大V的关注者名单时,当抓取到第10020个follower的时候程序就会报错,好像知乎有访问限制一般。这个问题,我还没有找到解决办法,希望有solution的告知一下。因为没有看到有用户关注10020+个人,因此抓取被关注者名单函数暂时未发现报错。
def get_followees(username):
# 直接输入用户名,关注者保存在以用户名命名的.txt文件中
followers_url = '/people/' + username + '/followees'
file_name = username + '.txt'
f = open(file_name, 'w')
data = s.get(followers_url, headers=header_info)
print data
# 访问服务器成功,返回
content = data.content
# 提取出html信息
soup = BeautifulSoup(content, &lxml&)
# 对html信息进行解析
# 获取关注者数量
totalsen = soup.select('span[class*=&zm-profile-section-name&]')
total = int(str(totalsen[0]).split(' ')[4])
# 总的关注者数量
txt1 = '总的关注者人数:'
print txt1.decode('utf-8')
print total
follist = soup.select('div[class*=&zm-profile-card&]')
# 记录有关注者信息的list
num = 0 # 用来在下面显示正在查询第多少个关注者
for follower in follist:
tag =follower.a
title = tag['title']
href = '' + str(tag['href'])
# 用户地址
# 获取用户数据
print '%d
%f' % (num, num / float(total))
# Alist = follower.find_all(has_attrs)
Alist = follower.find_all('a', {'target': '_blank'})
votes = Alist[0].string
# 点赞者获取的赞同
tks = Alist[1].string
# 点赞者获取的感谢
ques = Alist[2].string
# 点赞者提出的问题数量
ans = Alist[3].string
# 点赞者回答的问题数量
# 打印关注者信息
string = title + '
' + href + '
' + votes + tks + ques + ans
print string.decode('utf-8')
print string.encode('gbk', 'ignore')
f.write(string + '\n')
# 循环次数
n = total/20-1 if total/20.0-total/20 == 0 else total/20
for i in range(1, n+1, 1):
# if num%30 == 0:
time.sleep(1)
# if num%50 == 0:
time.sleep(2)
raw_hash_id = re.findall('hash_id(.*)', content)
hash_id = raw_hash_id[0][14:46]
_xsrf = xsrf
offset = 20*i
params = json.dumps({&offset&: offset, &order_by&: &created&, &hash_id&: hash_id})
payload = {&method&:&next&, &params&: params, &_xsrf&: _xsrf}
click_url = '/node/ProfileFolloweesListV2'
data = s.post(click_url, data=payload, headers=header_info)
# print data
source = json.loads(data.content)
for follower in source['msg']:
soup1 = BeautifulSoup(follower, 'lxml')
tag =soup1.a
title = tag['title']
href = '' + str(tag['href'])
# 用户地址
# 获取用户数据
print '%d
%f' % (num, num/float(total))
# Alist = soup1.find_all(has_attrs)
Alist = soup1.find_all('a', {'target': '_blank'})
votes = Alist[0].string
# 点赞者获取的赞同
tks = Alist[1].string
# 点赞者获取的感谢
ques = Alist[2].string
# 点赞者提出的问题数量
ans = Alist[3].string
# 点赞者回答的问题数量
# 打印关注者信息
string = title + '
' + href + '
' + votes + tks + ques + ans
print string.decode('utf-8')
print string.encode('gbk', 'ignore')
f.write(string + '\n')
提取用户头像
再往下就是抓取用户头像了。原来写的函数竟然找不到了,只找到了之前存放头像的文件夹,只好重写。这里我暂时先展示一下如何抓取到用户头像吧,完整的函数等有时间再补上。
今天没时间了,明后天补吧,到时候上完整函数。
抓取某个问题的所有答案
给出某个唯一ID,下面的函数帮助爬取到该问题下的所有答案。注意,答案内容只抓取文字部分,图片省略,答案保存在txt文件中,txt文件以答主ID命名。
def get_answer(questionID):
url = '/question/' + str(questionID)
data = s.get(url, headers=header_info)
soup = BeautifulSoup(data.content, 'lxml')
# print str(soup).encode('gbk', 'ignore')
title = soup.title.string.split('\n')[2]
# 问题题目
path = title
if not os.path.isdir(path):
os.mkdir(path)
description = soup.find('div', {'class': 'zm-editable-content'}).strings
# 问题描述,可能多行
file_name = path + '/description.txt'
fw = open(file_name, 'w')
for each in description:
each = each + '\n'
fw.write(each)
# description = soup.find('div', {'class': 'zm-editable-content'}).get_text() # 问题描述
# 调用.string属性返回None(可能是因为有换行符在内的缘故),调用get_text()方法得到了文本,但换行丢了
answer_num = int(soup.find('h3', {'id': 'zh-question-answer-num'}).string.split(' ')[0]) # 答案数量
index = soup.find_all('div', {'tabindex': '-1'})
for i in range(len(index)):
print ('Scrapying the ' + str(num) + 'th answer......').encode('gbk', 'ignore')
# print ('正在抓取第' + str(num) + '个答案......').encode('gbk', 'ignore')
a = index[i].find('a', {'class': 'author-link'})
title = str(num) + '__' + a.string
href = '' + a['href']
title = str(num) + '__匿名用户'
answer_file_name = path + '/' + title + '__.txt'
fr = open(answer_file_name, 'w')
answer_content = index[i].find('div', {'class': 'zm-editable-content clearfix'}).strings
answer_content = ['作者修改内容通过后,回答会重新显示。如果一周内未得到有效修改,回答会自动折叠。']
for content in answer_content:
fr.write(content + '\n')
_xsrf = xsrf
url_token = re.findall('url_token(.*)', data.content)[0][8:16]
# 循环次数
n = answer_num/10-1 if answer_num/10.0-answer_num/10 == 0 else answer_num/10
for i in range(1, n+1, 1):
# _xsrf = xsrf
# url_token = re.findall('url_token(.*)', data.content)[0][8:16]
offset = 10*i
params = json.dumps({&url_token&: url_token, &pagesize&: 10, &offset&: offset})
payload = {&method&:&next&, &params&: params, &_xsrf&: _xsrf}
click_url = '/node/QuestionAnswerListV2'
data = s.post(click_url, data=payload, headers=header_info)
data = json.loads(data.content)
for answer in data['msg']:
print ('Scrapying the ' + str(num) + 'th answer......').encode('gbk', 'ignore')
# print ('正在抓取第' + str(num) + '个答案......').encode('gbk', 'ignore')
soup1 = BeautifulSoup(answer, 'lxml')
a = soup1.find('a', {'class': 'author-link'})
title = str(num) + '__' + a.string
href = '' + a['href']
title = str(num) + '__匿名用户'
answer_file_name = path + '/' + title + '__.txt'
fr = open(answer_file_name, 'w')
answer_content = soup1.find('div', {'class': 'zm-editable-content clearfix'}).strings
answer_content = ['作者修改内容通过后,回答会重新显示。如果一周内未得到有效修改,回答会自动折叠。']
for content in answer_content:
fr.write(content + '\n')
数据库存取数据
在完成了上面的这些功能后,下一步要做的是将用户信息保存在数据库中,方便数据的读取使用。我刚刚接触了一下sqlite3,仅仅实现了将用户信息存储在表格中。
def get_followeesInfo_toDB(userID):
# 准备好sqlite3数据库,当抓取到数据时,加入表格中
conn = sqlite3.connect(&Zhihu.db&)
curs = conn.cursor()
curs.execute(&create table if not exists userinfo(name TEXT, ID TEXT PRIMARY KEY, location TEXT, business TEXT, &
&gender TEXT, employment TEXT, position TEXT, education TEXT, major TEXT, &
&agree INTEGER, thanks INTEGER, asks INTEGER, answers INTEGER, posts INTEGER, &
&collections INTEGER, logs INTEGER, followees INTEGER, followers INTEGER, &
&scantime INTEGER)&)
followees_url = '/people/' + userID + '/followees'
file_name = userID + '.txt'
f = open(file_name, 'w')
data = s.get(followees_url, headers=header_info)
print data
# 访问服务器成功,返回
content = data.content
# 提取出html信息
soup = BeautifulSoup(content, &lxml&)
# 对html信息进行解析
# 获取关注者数量
totalsen = soup.select('span[class*=&zm-profile-section-name&]')
total = int(str(totalsen[0]).split(' ')[4])
# 总的关注者数量
txt1 = '总的关注者人数:'
print txt1.decode('utf-8')
print total
follist = soup.select('div[class*=&zm-profile-card&]')
# 记录有关注者信息的list
# 用来在下面显示正在查询第多少个关注者
for follower in follist:
tag = follower.a
title = tag['title']
href = '' + str(tag['href'])
# 用户地址
# 获取用户数据
print '%d
%f' % (num, num / float(total))
# Alist = follower.find_all(has_attrs)
Alist = follower.find_all('a', {'target': '_blank'})
votes = Alist[0].string
# 点赞者获取的赞同
tks = Alist[1].string
# 点赞者获取的感谢
ques = Alist[2].string
# 点赞者提出的问题数量
ans = Alist[3].string
# 点赞者回答的问题数量
# 打印关注者信息
string = title + '
' + href + '
' + votes + tks + ques + ans
print string.decode('utf-8')
print string.encode('gbk', 'ignore')
f.write(string + '\n')
if title != '[已重置]':
# 获取该followee的基本信息,存入数据库表格
print 'Analysising the data of this user...'
ID = href[28:]
curs.execute(&insert or ignore into userinfo values (?, ?, ?, ?, ?, ?, ?, &
&?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)&, get_userInfo(ID))
print &This user account's state is abnormal...&
print 'This user account has been disabled...'
# print get_userInfo(ID)
# 循环次数
n = total / 20 - 1 if total / 20.0 - total / 20 == 0 else total / 20
for i in range(1, n + 1, 1):
# if num%30 == 0:
time.sleep(1)
# if num%50 == 0:
time.sleep(2)
raw_hash_id = re.findall('hash_id(.*)', content)
hash_id = raw_hash_id[0][14:46]
_xsrf = xsrf
offset = 20 * i
params = json.dumps({&offset&: offset, &order_by&: &created&, &hash_id&: hash_id})
payload = {&method&: &next&, &params&: params, &_xsrf&: _xsrf}
click_url = '/node/ProfileFolloweesListV2'
data = s.post(click_url, data=payload, headers=header_info)
# print data
source = json.loads(data.content)
for follower in source['msg']:
soup1 = BeautifulSoup(follower, 'lxml')
tag = soup1.a
title = tag['title']
href = '' + str(tag['href'])
# 用户地址
# 获取用户数据
print '%d
%f' % (num, num / float(total))
# Alist = soup1.find_all(has_attrs)
Alist = soup1.find_all('a', {'target': '_blank'})
votes = Alist[0].string
# 点赞者获取的赞同
tks = Alist[1].string
# 点赞者获取的感谢
ques = Alist[2].string
# 点赞者提出的问题数量
ans = Alist[3].string
# 点赞者回答的问题数量
# 打印关注者信息
string = title + '
' + href + '
' + votes + tks + ques + ans
print string.decode('utf-8')
print string.encode('gbk', 'ignore')
f.write(string + '\n')
if title != '[已重置]':
# 获取该followee的基本信息,存入数据库表格
print 'Analysising the data of this user...'
ID = href[28:]
curs.execute(&insert or ignore into userinfo values (?, ?, ?, ?, ?, ?, ?, &
&?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)&, get_userInfo(ID))
print &This user account's state is abnormal...&
print 'This user account has been disabled...'
# print get_userInfo(ID)
conn.close()
等熟悉了sqlite3的使用,我的下一步工作是抓取大量用户信息和用户之间的follow信息,尝试着将大V间的follow关系进行可视化。再下面的工作应该就是学习python的爬虫框架scrapy和爬取微博了。
另外,在写这篇博客的时候我又重新测试了一下上面的这些函数,然后我再在火狐上访问知乎时,提示&因为该账户过度频繁访问&而要求输入验证码,看来知乎已经开始限制爬虫了,这样以来我们就需要使用一些反反爬虫技巧了,比如控制访问频率等等,这个等以后有了系统的了解之后再作补充吧。

我要回帖

更多关于 python爬虫抓取图片 的文章

 

随机推荐