如何批量爬取知乎用户信息
首先声明,这次爬虫只做为测试使用。拿知乎练练手而已,不会做为其它用途。
正文开始,假如我要拿到用户如下的信息。
通过request请求其实还是比较容易的。直接 request.get 用户主页url 。返回的源码里面就有用户的详细资料信息,内容均到JavaScript代码里面。如下图。

通过正则表达式就能轻易的得到了。

问题来了,如何批量获取知乎用户呢?
我们第一反应肯定是,通过一个页面里面存在的其它用户的主页地址来获取多个页面。这样下去就能批量获取了。通过关注者或者被关注者?

想法是很好的,但是我发现 请求 被关注者信息的request请求头里面有一个参数,一直都是随机的。需要逆向分析js代码,找到规律,才能成功提交。但是这是很难的(至少我不会)
知乎在反爬方面做得好就是在这里。之前还是没有的。
下面到了解决问题的方案。
我采用的是selenium,我们第一反应肯定是,控制浏览器直接获取页面来得到关注者或者被关注者的信息。
但是你在知乎未登录的情况下,用selenium页面上根本就没有其它用户的信息。

回答里面没有,提问,文章,专栏想法,全部都是为空(因为知乎检测到了你是测试浏览器)。最后只能从动态入手。
有了这个想法,我写出了如下代码。
from concurrent.futures.thread import ThreadPoolExecutor
from selenium.webdriver.chrome.options import Options
from selenium.webdriver import Chrome
from lxml import etreeopt=Options()
opt.add_argument("--headless")
wait_data = set()
old_data=set()#获取新的url
def get_moreUrl(url):web = Chrome("D:\chromedriver.exe", options=opt)web.get(url)html = etree.HTML(web.page_source)web.close()divs=html.xpath('//*[@id="Profile-activities"]/div[2]/div')for div in divs:href=div.xpath('./div[2]/div/div[1]/div[1]/div/div/div[1]/span/div/div/a/@href')if href :new_href = "https:" + href[0]if not old_data.__contains__(new_href):wait_data.add(new_href)print(new_href) #获取页面详细信息
def get_data(url):web = Chrome("D:\chromedriver.exe", options=opt)web.get(url)web.find_element_by_xpath("/html/body/div[4]/div/div/div/div[2]/button").click()html = etree.HTML(web.page_source)name=html.xpath('//*[@id="ProfileHeader"]/div/div[2]/div/div[2]/div[1]/h1/span/text()')[0]num = html.xpath('//*[@id="root"]/div/main/div/meta[6]/@content')[0]answer_num=html.xpath('//*[@id="root"]/div/div[2]/header/div[2]/div/div/ul/li[2]/a/span/text()')[0]agree_num=html.xpath('//*[@id="root"]/div/main/div/meta[4]/@content')[0]like_num=html.xpath('//*[@id="root"]/div/main/div/meta[5]/@content')[0]web.close()list=[url,name,num,answer_num,agree_num,like_num]print(list)if __name__ == '__main__':wait_data.add("https://www.zhihu.com/people/system-out-99")with ThreadPoolExecutor(10) as t:while True:if wait_data.__len__()>0:url = wait_data.pop()old_data.add(url)t.submit(get_moreUrl,url)t.sumbmit(get_data,url)
其实代码并不难,我觉得这个思路过程还是最重要的。虽然selenium效率并不高。但是加上线程池效率也是很客观了。1分钟几十条还是可行叭。
如果有大佬在代码上能有什么提高效率的建议。欢迎和我交流一下。
最后我的公众号: 爬虫代写
欢迎关注。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
