python爬虫——知乎(关于python的精华回答)

<strong>之前的文章都是与职位、热门文章有关的,今天一起来看一下知乎上与python相关的精华回答(主要是requests,scrapy处理的思路,编码问题)</strong>

知乎python精华回答

1.采集的信息

<ol>
<li>问题题目</li><li>问题对应URL</li><li>回答的作者</li><li>作者主页URL</li><li>回答获赞数</li><li>回答详情URL</li></ol><strong>主要获取以上信息,接着我们来看一下这些字段所在的位置

字段位置

通过观察和分析以上字段在源码中都能找到,所以就不用像前几篇文章那样,构造参数,解析获取返回的json数据,我们可以通过lxml.etree.HTML()或者Beautifulsoup去解析(这里在通过etree解析时遇到了一些问题,在后边会进行解释)
既然不需要通过构造参数去获取数据了,所以相对来说就简单一些了,接下来我们来看一下另一个很重要的问题——分页问题</strong>

第一页
第二页

<em>从上面两张图片我们可以看出换页之后参数<strong>page</strong>发生了改变,很显然<strong>page</strong>控制的是页码,明白了这一点就可以去构造URL了</em>

2.构造URL

总页数
urls = ['https://www.zhihu.com/topic/19552832/top-answers?page={}'.format(one) for one in range(1,51)]

<strong>解决了分页问题,就没什么难点了,接下来说一下遇到的问题和解决方法

  • 通过Beautifulsoup解析页面
# -*- coding:utf-8 -*-
import requests
from bs4 import BeautifulSoup
from store_csv import CSV
from store_mysql import Mysql
class zhiHu(object):
    baseurl = 'https://www.zhihu.com'
    headers = {
        "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"
    }
    cookies = {
        'd_c0': '"AHACIj6lFguPTkEZTVmz8MPJ8UkcuI03hag=|1483278273"',
        '_zap': '108369f2-93e6-407e-8928-b57f44168838',
        'q_c1': '0d3d690c67bc4b12a163beb462e17d67|1492571575000|1483278273000',
        'cap_id': '"NmFlNDgyZmMxNWQ0NGFiYmFhZThmMGM2MDVkZDM1MWM=|1493684435|1958b2bb9fb6f09116056cc4bc5af76e00dbaff7"',
        'l_cap_id': '"ZjViYmQ0MzBkNTFjNGJjOWE5YTExZWRjMjlkNjM2YjQ=|1493684435|1204e5c054805d8bebf3b49a8a2fc09e2f1bd870"',
        'auth_type': '"c2luYQ==|1493684515|245a0f575f151c486829c687ba3d3c90fc5fa558"',
        'token': '"Mi4wMGljWjNYRkVBNzIyRGJjZDZkMjMyZmMwM2JtMWs=|1493684515|a76491c048b7e825a77983ef0a272bdc9e721853"',
        'client_i': '"NTA3MzY2MzQwNA==|1493684515|9a08a2c9a6c02e86da4810cb5bc4437f6d7b1028"',
        'aliyungf_tc': 'AQAAAFOsE04F5QQAHVcc2i2qHTGdX1x0',
        'acw_tc': 'AQAAAAnnBnQS0AcAHVcc2omDblHld+wt',
        '_xsrf': '398e0b041f39355dadfc06b76ba18cdb',
        's-q': 'python',
        's-i': '1',
        'sid': 'ob2ttqkg',
        's-t': 'autocomplete',
        'z_c0': 'Mi4wQUFBQ3hmbTFzUXNBY0FJaVBxVVdDeGNBQUFCaEFsVk5OVjR2V1FETW9QS19PRlExWGVjUHNOcFVoTG5mYWg1LUtR|1493701061|4258e8f2ddc800c42c8b7d94385f578ca97f34d5',
        '__utma': '51854390.213172690.1484833633.1493684449.1493701029.4',
        '__utmb': '51854390.0.10.1493701029',
        '__utmc': '51854390',
        '__utmz': '51854390.1493701029.4.4.utmcsr=baidu|utmccn=(organic)|utmcmd=organic',
        '__utmv': '51854390.100--|2=registration_date=20170502=1^3=entry_date=20170101=1'
    }
    def getUrl(self):
        urls = ['https://www.zhihu.com/topic/19552832/top-answers?page={}'.format(one) for one in range(1,51)]
        for url in urls:
            self.getData(url)
    def getData(self,url):
        data = requests.get(url, headers=self.headers, cookies=self.cookies).content.encode('utf-8')
        soup = BeautifulSoup(data, 'lxml')
        infos = soup.find_all('div', {'class': 'feed-item feed-item-hook folding'})
        item = {}
        for info in infos:
            item[1] = info.find('a',{'class':'question_link'}).get_text().strip()
            item[1] = item[1].replace("'","=")
            item[2] = self.baseurl+info.find('a',{'class':'question_link'}).get('href')
            try:
                item[3] = info.find('a',{'class':'author-link'}).get_text()
            except:
                item[3] = u'匿名用户'
            try:
                item[4] = self.baseurl+info.find('a',{'class':'author-link'}).get('href')
            except:
                item[4] = u''
            item[5] = info.find('a',{'class':'zm-item-vote-count js-expand js-vote-count'}).get_text()
            try:
                item[6] = self.baseurl+info.find('a',{'class':'toggle-expand'}).get('href')
            except:
                item[6] = u''
            self.store(item)
    def store(self,item={}):
        #row = [item[i] for i in range(1,7)]
        #wirte.writeRow(row)
        mysql.insert(item)
if __name__ == "__main__":
    #firstRow = ['问题', '问题URL', '回答者', '回答者URL', '获赞', '详细信息URL']
    #wirte = CSV('zhihu.csv',firstRow)
    row = ['question','qurl','autuor','aurl','zan','detail']
    mysql = Mysql('zhihu',row,7)
    mysql.create_table()
    zhihu = zhiHu()
    zhihu.getUrl()

</strong><em>这里说明一点,from store_csv import CSV,from store_mysql import Mysql这两个是自己写的两个类,实现方法可以参考python简单操作csv文件小例和老哥Mr_Cxypython对Mysql数据库的操作小例这两篇文章,这里可以不添加cookie信息</em>
<strong>

  • 通过etree解析页面(和之前一样都是找到循环点,然后取值,这里主要说一下遇到的问题和解决的方法)
  • 问题</strong>
    html = requests.get(url,headers=headers)
    这里有不同方式,一种是html.content,另一种是html.text之前没遇到出错的情况(通过content出现了编码问题,python版本2.7),今天遇到了就记录一下:
    resp.text返回的是Unicode型的数据。
    resp.content返回的是bytes型也就是二进制的数据。
    也就是说,如果你想取文本,可以通过r.text。
    如果想取图片,文件,则可以通过r.content。
  • <strong>方法</strong>
    主要说一下html.content的解决方案
selector = etree.HTML(html.content.decode('utf-8'))

通过对html.content进行解码,输出结果正常。

3.scrapy版本思路

  • <strong>1.使用start_requests()重写初始URL控制或者在parse函数中进行分页的控制
yield scrapy.Request(url,callback=self.parse)

</strong><em>代码中提到的URL指的是下一页的URL,通过获取下一页信息调用parse函数抓取信息</em><strong>

下一页
  • 2.之前通过观察URL,我们发现只有page之后的数字发生了变化,所以我们可以使用爬取规则CrawlSpider去获取不同页面的信息(给一个之前抓取智联招聘职位详情页面的规则作为参考)
        # -*- coding: utf-8 -*-
        from scrapy.spider import CrawlSpider,Rule
        from scrapy.linkextractors import LinkExtractor
        from ..items import ZlzpItem
    
        class ZLZP_Spider(CrawlSpider):
            name = 'ZLZP'
            start_urls = [
                'http://jobs.zhaopin.com/'
            ]
            rules = [
            Rule(LinkExtractor(allow=('http://jobs.zhaopin.com/[a-zA-Z0-9]*\.htm',)), follow=True,
               callback='parse_item')]
            def parse_item(self, response):
    

这里使用了parse_item进行页面数据的提取(编写爬虫规则时,避免使用 parse 作为回调函数。 由于 CrawlSpider
使用 parse方法来实现其逻辑,如果覆盖了 parse方法,crawl spider 将会运行失败。)
关于CrawlSpider
的详细使用方法可以参考官方文档或者参考相关的代码和文章

4.数据信息(mysql和csv)

mysql
zhihu.csv

总结

通过对比动态网页(ajax)和静态网页,在思想上差别不是很大(参数+分页),在解析方式动态的一般都是通过解析json来获取数据,静态则通过Beautifulsoup、xpath、正则去获取数据。
爬爬爬,下一个网站走起!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容