• python爬虫面试题集锦及答案


    1.爬取数据后使用哪个数据库存储数据的,为什么?

    MySQL

    1. 数据同步插入数据库

    在pipelines.py中引入数据库连接模块:

    __init__是对数据进行初始化,定义连接信息如host,数据库用户名、密码、数据库名称、数据库编码, 在process_item中进行插入数据操作,格式都是固定的

    1. class MysqlPipeline(object):
    2. def __init__(self):
    3. self.conn = MySQLdb.connect('127.0.0.1', 'root', 'root', 'jobbole', charset='utf8', use_unicode=True)
    4. self.cursor = self.conn.cursor()
    5. def process_item(self, item, spider):
    6. insert_sql = 'INSERT INTO jobbole_article (`title`, `create_date`, `url`, `url_object_id`, `content`, `front_image_path`, `comment_nums`, `fav_nums`, `praise_nums`, `tags`) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)'
    7. self.cursor.execute(insert_sql, (item['title'], item['create_date'], item['url'], item['url_object_id'], item['content'], item["front_image_path"], item['comment_nums'], item['fav_nums'], item['praise_nums'], item['tags']))
    8. self.conn.commit()

    最后在settings.py中把MysqlPipelint()加入到系统中,需要注意的是优先级要小于之前加入处理图片路径的优先级

    (先进行ArticleimagePipeline的处理,再进行MysqlPipeline处理)

    1. ITEM_PIPELINES = {
    2. 'articlespider.pipelines.ArticlespiderPipeline': 300, #系统自动生成pipeline,未用
    3. 'articlespider.pipelines.ArticleimagePipeline': 1,
    4. 'articlespider.pipelines.MysqlPipeline': 4,
    5. }
    1. 异步插入数据库
      异步操作需要引入twisted:
    1. from twisted.enterprise import adbapi
    2. import MySQLdb
    3. import MySQLdb.cursors
    1. class MysqlPipeline(object):
    2. def __init__(self, dbpool):
    3. self.dbpool = dbpool
    4. @classmethod
    5. def from_settings(cls, settings):
    6. dbparms = dict(
    7. host = settings["MYSQL_HOST"],
    8. db = settings["MYSQL_DBNAME"],
    9. user = settings["MYSQL_USER"],
    10. passwd = settings["MYSQL_PASSWORD"],
    11. charset='utf8',
    12. cursorclass=MySQLdb.cursors.DictCursor,
    13. use_unicode=True,
    14. )
    15. dbpool = adbapi.ConnectionPool("MySQLdb", **dbparms)
    16. return cls(dbpool)
    17. def process_item(self, item, spider):
    18. # 使用twisted将mysql插入变成异步执行
    19. query = self.dbpool.runInteraction(self.do_insert, item)
    20. query.addErrback(self.handle_error)
    21. def handle_error(self, failure):
    22. print(failure)
    23. def do_insert(self, cursor, item):
    24. # 具体执行插入
    25. insert_sql = 'INSERT INTO jobbole_article (`title`, `create_date`, `url`, `url_object_id`, `content`, `front_image_path`, `comment_nums`, `fav_nums`, `praise_nums`, `tags`) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)'
    26. cursor.execute(insert_sql, (item['title'], item['create_date'], item['url'], item['url_object_id'], item['content'], item["front_image_path"], item['comment_nums'], item['fav_nums'], item['praise_nums'], item['tags']))

    2.你用过的爬虫框架或者模块有哪些?优缺点?

    1.Scrapy

    Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。。用这个框架可以轻松爬下来如亚马逊商品信息之类的数据。

    2.Beautiful Soup

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间。

    3.写爬虫是用多进程好?还是多线程好?

    IO密集型代码(文件处理、网络爬虫等),多线程能够有效提升效率(单线程下有IO操作会进行IO等待,造成不必要的时间浪费,而开启多线程能在线程A等待时,自动切换到线程B,可以不浪费CPU的资源,从而能提升程序执行效率)。在实际的数据采集过程中,既考虑网速和响应的问题,也需要考虑自身机器的硬件情况,来设置多线程或多进程

    4.常见的反爬虫和应对方法?

     从功能上来讲,爬虫一般分为数据采集,处理,储存三个部分。这里我们只讨论数据采集部分。

      一般网站从三个方面反爬虫:用户请求的Headers,用户行为,网站目录和数据加载方式。前两种比较容易遇到,大多数网站都从这些角度来反爬虫。第三种一些应用ajax的网站会采用,这样增大了爬取的难度。

     0x02 通过Headers反爬虫

      从用户请求的Headers反爬虫是最常见的反爬虫策略。很多网站都会对Headers的User-Agent进行检测,还有一部分网站会对Referer进行检测(一些资源网站的防盗链就是检测Referer)。如果遇到了这类反爬虫机制,可以直接在爬虫中添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者将Referer值修改为目标网站域名。对于检测Headers的反爬虫,在爬虫中修改或者添加Headers就能很好的绕过。

     0x03 基于用户行为反爬虫

      还有一部分网站是通过检测用户行为,例如同一IP短时间内多次访问同一页面,或者同一账户短时间内多次进行相同操作。

      大多数网站都是前一种情况,对于这种情况,使用IP代理就可以解决。可以专门写一个爬虫,爬取网上公开的代理ip,检测后全部保存起来。这样的代理ip爬虫经常会用到,最好自己准备一个。有了大量代理ip后可以每请求几次更换一个ip,这在requests或者urllib2中很容易做到,这样就能很容易的绕过第一种反爬虫。

      对于第二种情况,可以在每次请求后随机间隔几秒再进行下一次请求。有些有逻辑漏洞的网站,可以通过请求几次,退出登录,重新登录,继续请求来绕过同一账号短时间内不能多次进行相同请求的限制。

     0x04 动态页面的反爬虫

      上述的几种情况大多都是出现在静态页面,还有一部分网站,我们需要爬取的数据是通过ajax请求得到,或者通过JavaScript生成的。首先用Firebug或者HttpFox对网络请求进行分析。如果能够找到ajax请求,也能分析出具体的参数和响应的具体含义,我们就能采用上面的方法,直接利用requests或者urllib2模拟ajax请求,对响应的json进行分析得到需要的数据。

      能够直接模拟ajax请求获取数据固然是极好的,但是有些网站把ajax请求的所有参数全部加密了。我们根本没办法构造自己所需要的数据的请求。我这几天爬的那个网站就是这样,除了加密a

  • 相关阅读:
    浅谈数字孪生产业应用与标准----工业软件讲坛第七次讲座
    [HTML]常用标签的使用
    MySQL学习记录(6)索引02
    【ARFoundation学习笔记】平面检测
    kubernetes集群配置默认存储类(nfs)
    Golang 包了解以及程序的执行
    SpringBoot日志基础
    【c】指针
    智能变电站网络报文记录及故障录波分析装置
    R语言使用table1包绘制(生成)三线表、使用双变量分列构建三线表、双变量分列三线表、自定义调换双变量的顺序从不同角度分析查看
  • 原文地址:https://blog.csdn.net/AudiA6LV6/article/details/126921615