python 爬取世纪佳缘,经过js渲染过的网页的爬取

news/2024/7/19 12:38:16 标签: json, 爬虫, 开发工具
#!/usr/bin/python
#-*- coding:utf-8 -*-

#爬取世纪佳缘
#这个网站是真的烦,刚开始的时候用scrapy框架写,但是因为刚接触框架,碰到js渲染的页面之后就没办法了,所以就采用一般的爬虫了
#js渲染过的数据,可能在网页源码里面没有数据,需要js异步请求提取数据,然后展示,所以爬取这类的数据,只需要找到js发送请求的url就行了
#js发送的请求可能是post(比如这个例子)或者是get(比如豆瓣电影剧情的排行榜),所以要看好是什么请求

import sys
import json 
#from lxml import etree
import urllib
import urllib2 


reload(sys)
sys.setdefaultencoding("utf-8") #设置默认的编码格式,把Unicode格式转换成汉字写到文件里面的时候需要用到,要配合decode("unicode_escape")使用

class shiji():
    def __init__(self):
        self.page = 1 #初始化页面的第几页
        self.filename = open("sj.json","w") #打开文件用于写入数据

    def parse_page(self):
        url = "http://search.jiayuan.com/v2/search_v2.php?" #初始url的前半段,加上后半段发送的是post请求
        headers = {"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"}
        formdata = {
                "sex":"f",
                "key":"",
                "stc":"1:11,2:20.25,3:160.170,23:1",
                "sn":"default",
                "sv":"1",
                "p":self.page, #每次数据js异步提取数据的时候只有p变化了,p对应于当前页面是第几页 
                "f":"select",
                "listStyle":"bigPhoto",
                "pri_uid":"170633820",
                "jsversion":"v5"
            }
        data = urllib.urlencode(formdata)
        request = urllib2.Request( url ,data = data , headers = headers)
        response = urllib2.urlopen(request)
#        print response.info().get('Content-Encoding') #这会打印出服务器返回数据的压缩方式,如果未有压缩则返回None
        js = response.read() #返回的response.read()是json格式的,但是首和尾多了一段字符串"##jiayse##"和"##jiayse##",所以下面就处理一下
        
        #print type(js) #字符串类型
        js = js.replace("##jiayser##","").replace("//","") #字符串里很牛X的一个函数replace()
        #print js 
        content = json.loads(js) #字典类型(这个字典是大字典,key只有isLogin、count、pageTotal、userInfo,其中userInfo是每个人的资料)
        
        self.parse_person(content['userInfo']) #调用parse_person函数处理大字典的ueerInfo(还是字典类型的),即每个人的资料
#            print type(content['userInfo'])#字典类型

    def parse_person(self,userinfo):
        for i in range(len(userinfo)):
            
            form = {"昵称":userinfo[i]['nickname'],"年龄":userinfo[i]['age'],"内心独白":userinfo[i]['shortnote']} #把要爬取的数据写成一个字典
            
            #print form 
            #print type(form)
            
            #不能把dict和list类型直接写入文件, 把字典写入json文件的时候要把字典转换成json字符串才行(json.dumps(form))
            #decode("unicode_escape")表示把unicode格式转换成汉字,但用一个这竟然还不行!还要加上上面的import sys... , 真麻烦
            form = json.dumps(form).decode("unicode_escape") 
            
            self.filename.write(form+"\n") #写入文件

        if self.page <10: #这里随便写self.page,只要不超过页面加载的范围就行
            self.page+=1
            self.parse_page() #自加一之后在调用parse_page()函数进行换页,然后接着爬

if __name__ == "__main__":
    sj = shiji()
    sj.parse_page() #调用parse_page()函数开始爬取
写这个爬虫浪费了一天的时间。。。我是真的菜。

错误总结:
关于unicode编码转汉字的方法以及UnicodeEncodeError: 'ascii' codec can't encode characters in position问题: 
 https://www.cnblogs.com/technologylife/p/6071787.html   
 http://blog.sina.com.cn/s/blog_64a3795a01018vyp.html

把dict写入文件的时候碰见的报的typeError的解决办法: http://blog.csdn.net/guoweish/article/details/47106263

另外加一篇ubuntu vim撤销操作的博客  http://blog.sina.com.cn/s/blog_7e9efc570101ays3.html

收获:这次的收获还可以,解决了很多没见过的bug,第一次爬取js渲染的网页的数据,值得记得的是:(1).js渲染过得网页怎么找数据来源(f12 network XHR 找是post请求还是get请求),(2)字符串的强大替换函数replace,(3)字典写入文件怎么处理  (先转换成json的字符串再写入),(4)unicode转汉字怎么处理(import sys + decode("unicode_escape"))

转载于:https://www.cnblogs.com/nyist-xsk/p/7875295.html


http://www.niftyadmin.cn/n/1345420.html

相关文章

ASA5505透明模式

未配置时 ciscoasa# show run : Saved:ASA Version 7.2(3) !hostname ciscoasaenable password 8Ry2YjIyt7RRXU24 encryptednames!interface Vlan1nameif insidesecurity-level 100ip address 192.168.1.1 255.255.255.0 !interface Vlan2nameif outsidesecurity-level 0ip add…

ac自动机学习

好的文章&#xff1a; ac自动机原理 ac自动机原理 题目&#xff1a; hdu 2778 ac自动机加矩阵快速幂(这篇题解很清晰) 题意&#xff1a;有m种DNA序列是有疾病的&#xff0c;问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列。&#xff08;仅含A,T,C,G四个字符&am…

Zookeeper异常ConnectionLossException解决

Zookeeper异常ConnectionLossException解决CentOS关闭防火墙命令&#xff1a;[python] view plaincopyCentOS Linux开启和关闭防火墙命令有两种&#xff0c;一种是临时的&#xff0c;重启即复原&#xff1b;另外一种是永久性的&#xff0c;重启不会复原。 1&#xff09; 临时生…

救市重炮轮番轰炸 美欧央行联手将无限额注资

中国经济网10月14日电 趁着上周末IMF和世行年会的东风&#xff0c;以美欧为首的西方国家过去两天进一步加大救市力度。欧元区15国上周日终于通过了包括注资和债务担保等内容的银行救援方案&#xff0c;美国的类似计划也有望在本周出台&#xff0c;英国13日宣布斥资370亿欧元注资…

hdu 4616 Game (树形dp)

Game Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 2007 Accepted Submission(s): 649 Problem Description   Nowadays, there are more and more challenge game on TV such as ‘Girls, Rush Ahead’. No…

PHP_EOL是什么意思?

PHP_EOL 代表php的换行符&#xff0c; 这个变量会根据平台而变&#xff0c; 在windows下会是/r/n&#xff0c; 在linux下是/n&#xff0c; 在mac下是/r 文章来源&#xff1a;刘俊涛的博客 地址&#xff1a;http://www.cnblogs.com/lovebing 转载于:https://www.cnblogs.com/lov…

北电PBX资料_LD 95 顯示姓名設定程式

LD 95 顯示姓名設定程式 程式提示 輸入指令符號 說 明 備 註 REQ NEW 新增 CHG 修改 OUT 刪除 PRT 列印 END 結束程式 TYPE CPND 顯示姓名檔案設定 NAME 姓名設定 CUST 0-31 客戶群編號 TYPE CPND MXLN 5-(17)-27 最長之姓名長度 RESN (NO)/YES 是否顯示前轉模式 CFWD xxxx 跟隨…

CCNA10月22号战报

10月22日 河北石家庄976 _ 10月22日 965 pass<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />下午2点开始考试&#xff0c;照相&#xff0c;签字什么的不说了&#xff01;考试时间是140分钟&#xff0c;不是网上说的150分钟&…