当前位置: 首页 > 科技观察

一个合格的数据分析师分享关于Python网络爬虫的二三事(综合实战案例)

时间:2023-03-16 10:07:39 科技观察

接上篇文章《一名合格的数据分析师分享Python网络爬虫二三事》5.综合实战案例1.爬取静态网页数据(1)需要爬取豆瓣网出版公司名称,分别存储到excel、txt、mysql数据库中。(2)分析查看源码Ctrl+F搜索任意出版社名称,如博集天卷确定正则模式“(.*?)

”(3)idea下载目标页面正则匹配目标内容Python列表存储写入Excel/txt/MySQL(四)源码''信息存储'''importurllibimportreimportxlsxwriteimportMySQLdb#----------------(1)存储到excel和txt------------------------#defgxls_concent(target_url,pat):'''功能:爬取数据@target_url:爬取目标URL@pat:数据过滤模式'''data=urllib.request.urlopen(target_url).read()reret_concent=re.compile(pat).findall(str(data,'utf-8'))returnret_concentdefwxls_concent(ret_xls,ret_concent):'''作用:将最终结果写入douban.xls@ret_xls:最终结果在excel表格中的存放路径@ret_concent:爬取数据结果列表'''#打开finalwrittenfilewb1=xlsxwriter.Workbook(ret_xls)#创建sheet工作对象ws=wb1.add_worksheet()try:foriinrange(len(ret_concent)):data=ret_concent[i]ws.write(i,0,data)wb1.close()exceptExceptionaser:print('write进入“'+ret_xls+'”文件时出错')print(er)defwtxt_concent(ret_txt,ret_concent):'''功能:将最终结果写入douban.txt@ret_xls:最终结果存放excel表的路径@ret_concent:抓取数据结果列表'''fh=open(ret_txt,"wb")try:foriinrange(len(ret_concent)):data=ret_concent[i]datadata=data+"\r\n"datadata=data.encode()fh.write(data)exceptExceptionaser:print('write"'+ret_txt+'"Therewasanerrorinthefile')print(er)fh.close()defmainXlsTxt():'''功能:将数据存入excel表格'''target_url='https://read.douban.com/provider/all'#抓取目标URLpat='
(.*?)
'#抓取方式ret_xls="F:/spider_ret/douban.xls"#excel文件路径ret_txt="F:/spider_ret/douban.txt"#txt文件路径ret_concent=gxls_concent(target_url,pat)#获取数据wxls_concent(ret_xls,ret_concent)#写excel表wtxt_concent(ret_txt,ret_concent)#写txt文件#---------------------结束(1)--------------------------------##----------------(2)存储到MySQL--------------------------#defdb_con():'''功能:连接MySQL数据库'''con=MySQLdb.connect(host='localhost',#portuser='root',#usr_namepasswd='xxxx',#passnamedb='urllib_data',#db_namecharset='utf8',local_infile=1)returncondefexeSQL(sql):'''功能:数据库查询function@sql:定义SQL语句'''print("exeSQL:"+sql)#connectiondatabasecon=db_con()con.query(sql)defgdb_concent(target_url,pat):'''功能:将爬取的数据转换为插入数据库格式:[[value_1],[value_2],...,[value_n]]@target_url:爬取目标URL@pat:数据过滤模式'''tmp_concent=gxls_concent(target_url,pat)ret_concent=[]foriinrange(len(tmp_concent)):ret_concent.append([tmp_concent[i]])returnret_concentdefwdb_concent(tbl_name,ret_concent):'''功能:将爬取结果写入MySQL数据库@tbl_name:数据表名@ret_concent:爬取数据结果列表'''exeSQL("droptableifexists"+tbl_name)exeSQL("createtable"+tbl_name+"(pro_nameVARCHAR(100));")insert_sql="insertinto"+tbl_name+"values(%s);"con=db_con()cursor=con.cursor()try:cursor.executemany(insert_sql,ret_concent)exceptExceptionaser:print('执行MySQL:"Errorin'+str(insert_sql)+'"')print(er)finally:cursor.close()con.commit()con.close()defmainDb():'''功能:将数据存储到MySQL数据库中'''target_url='https://read.douban.com/provider/all'#抓取目标URLpat='
(.*?)
'#爬取模式tbl_name="provider"#数据表名#获取数据ret_concent=gdb_concent(target_url,pat)#写入MySQL数据库wdb_concent(tbl_name,ret_concent)#--------------------END(2)------------------------------#if__name__=='__main__':mainXlsTxt()mainDb()(5)结果二、基于Ajax技术爬取网页数据(1)需要爬取拉勾网广州的数据挖掘职位信息,存储到本地Excel文件中(2)分析a.工作数据在哪里?打开拉勾网==》输入关键字“数据挖掘”==查看源代码==”未找到职位信息打开拉勾网==”输入关键字“数据挖掘”==”按F12==”网络刷新==按下图发现position和companyfile开头有一个json,这大概就是我们需要的post信息,右键选择openlinkinnewtab,就可以找到了是我们需要的b.如何实现翻页?我们写爬虫的时候,需要爬取多个页面。自动模拟一个pagefeed操作。首先我们点击下一页,可以看到url有没有改变,这是Ajax(异步加载)的技术,点击该位置的json文件,点击右侧的Headers栏,可以发现第一部分有如下内容:当我们改变页面时,pn变成2先变成false,所以我们可以通过构造post表单来爬取。C。Json数据结构怎么样?(3)源码importurllib.requestimporturllib.parseimportsocketfrommultiprocessing.dummyimportPoolimportjsonimporttimeimportxlsxwriter#----------------------------------------------------------#######(1)获取代理IP###defgetProxies():'''功能:调用获取原始代理IP池的API'''url="http://api.xicidadaili.com/free2016.txt"i_headers={"User-Agent":"Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/49.0.2623.22Safari/537.36SE2.XMetaSr1.0"}globalproxy_addrproxy_addr=[]try:req=urllib.request.Request(url,headers=i_headers)proxy=urllib.request.urlopen(req).read()proxyproxy=proxy.decode('utf-8')proxyproxy_addr=proxy.split('\r\n')#设置分隔符为换行exceptExceptionaser:print(er)returnproxy_addrdeftestProxy(curr_ip):'''功能:使用百度首页逐一验证代理IP合法性@curr_ip:当前验证IP'''socket.setdefaulttimeout(5)#设置全局超时tarURL="https://www.baidu.com/"#测试URL代理y_ip=[]try:proxy_support=urllib.request.ProxyHandler({"http":curr_ip})opener=urllib.request.build_opener(proxy_support)opener.addheaders=[("User-Agent","Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/49.0.2623.22Safari/537.36SE2.XMetaSr1。0")]urllib.request.install_opener(opener)res=urllib.request.urlopen(tarURL).read()proxy_ip.append(curr_ip)print(len(res))exceptExceptionaser:print("验证代理IP("+curr_ip+"):"+er)returnproxy_ipdefmulTestProxies(proxies_ip):'''功能:构建所有代理IP的多进程验证@proxies_ip:代理IP池'''pool=Pool(processes=4)#Open四个进程proxies_addr=pool.map(testProxy,proxies_ip)pool.close()pool.join()#等待进程池中的worker进程完成returnproxies_addr#------------------------------------------------------------#######(2)抓取数据###defgetInfoDict(url,page,pos_words_one,proxy_addr_one):'''功能:获取单页位置数据,返回数据字典@url:目标URL@page:抓取页面@pos_words_one:搜索关键词(单个)@proxy_addr_one:proxyIPused(single)'''globalpos_dictpage=1i_headers=("User-Agent","Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/49.0.2623.22Safari/537.36SE2.XMetaSr1.0")proxy=urllib.request.ProxyHandler({"http":proxy_addr_one})opener=urllib.request.build_opener(proxy,urllib.request.HTTPHandler)opener.addheaders=[i_headers]urllib.request.install_opener(opener)ifpage==1:tORf="true"else:tORf="false"mydata=urllib.parse.urlencode({"first":tORf,"pn":page,#pn改变实现翻页"kd":pos_words_one}).encode("utf-8")try:req=urllib.request.Request(url,mydata)data=urllib.request.urlopen(req).read().decode("utf-8","ignore")#使用代理ip打开pos_dict=json.loads(data)#将str转换成dictexcepturllib.error.URLErroraser:ifhasattr(er,"code"):print("获取职位信息json对象时出现URLError,错误码:")print(er.code)ifhasattr(er,"reason"):print("获取职位信息json对象时出现URLError,错误原因:")print(er.reason)returnpos_dictdefgetInfoList(pos_dict):'''功能:将getInfoDict()返回的数据字典转换成datalist@pos_dict:位置信息数据字典'''pos_list=[]#职位信息列表jcontent=pos_dict["content"]["positionResult"]["result"]foriinjcontent:one_info=[]#一个职位的相关信息one_info.append(i["companyFullName"])one_info.append(i['companySize'])one_info.append(i['positionName'])one_info.append(i['education'])one_info.append(i['financeStage'])one_info.append(i['salary'])one_info.append(i['city'])one_info.append(i['district'])one_info.append(i['positionAdvantage'])one_info.append(i['workYear'])pos_list.append(one_info)returnpos_listdefgetPosInfo(pos_words,city_words,proxy_addr):'''功能:基于函数getInfoDict()和getInfoList(),循环遍历每个页面,获取所有职位信息的最终列表@pos_words:职位关键词(多个)@city_words:限制城市关键词(多个)@proxy_addr:使用的代理IP池(多个)'''posInfo_result=[]title=['公司全名','公司规模','职位','学历','财务status',"薪资水平","城市","地区","优势","工作经验"]posInfo_result.append(title)foriinrange(0,len(city_words)):#i=0key_city=urllib。request.quote(city_words[i])#过滤关键词设置:gj=freshgraduate&xl=collegecollege&jd=growthtype&hy=移动互联网&px=new&city=广州url="https://www.lagou.com/jobs/positionAjax.json?city="+key_city+"&needAddtionalResult=false"forjinrange(0,len(pos_words)):#j=0page=1whilepage<10:#每个关键字搜索钩子显示30页,这里只抓取10页pos_wordspos_words_one=pos_words[j]#k=1proxy_addrproxy_addr_one=proxy_addr[page]#page+=1time.sleep(3)pos_info=getInfoDict(url,page,pos_words_one,proxy_addr_one)#获取单页信息列表pos_infoList=getInfoList(pos_info)posInfo_result+=pos_infoList#累加所有页面信息page+=1returnposInfo_result#----------------------------------------------------------#######(3)存储数据###defwXlsConcent(export_path,posInfo_result):'''功能:将最终结果写入本地excel文件@export_path:导出路径@posInfo_result:爬取数据列表'''#打开最终写入文件wb1=xlsxwriter.Workbook(export_path)#创建sheet工作对象ws=wb1.add_worksheet()try:foriinrange(0,len(posInfo_result)):forjinrange(0,len(posInfo_result[i])):data=posInfo_result[i][j]ws.write(i,j,data)wb1.close()exceptExceptionaser:print('写入时出现“'+export_path+'”文件错误:')print(er)#----------------------------------------------------------#######(4)定义main()函数###defmain():'''功能:主函数,调用相关函数,最终输出路径(F:/spider_ret)下的positionInfo.xls文件'''#---(1)获取代理IP池proxies=getProxies()#获取原始代理IPproxy_addr=mulTestProxies(proxies)#Multi-线程测试原始ProxyIP#---(2)抓取数据search_key=["数据挖掘"]#设置职位关键词(可设置多个)city_word=["广州"]#设置搜索区域(可设置多个)posInfo_result=getPosInfo(search_key,city_word,proxy_addr)#抓取位置信息#---(3)存储数据export_path="F:/spider_ret/positionInfo.xls"#设置导出路径wXlsConcent(export_path,posInfo_result)#写入excelif__name__=="__main__":main()继续下一篇《一名合格的数据分析师分享Python网络爬虫二三事(Scrapy自动爬虫)》【本文为栏目组织《奇安科技》原创文章,转载请微信联系原作者?(bigsec)】点击这里ee作者的更多好文章