dataabc / weibo-search

获取微博搜索结果信息,搜索即可以是微博关键词搜索,也可以是微博话题搜索
1.71k stars 374 forks source link

使用情况反馈 #1

Open barnett2010 opened 4 years ago

barnett2010 commented 4 years ago

大佬。是不是改这几个地方就可以使用了

'Accept':
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-US;q=0.7',
'cookie': 'your cookie'

settings.py 里的cookies也是weibo.cn获取

class SearchSpider(scrapy.Spider): name = 'search' allowed_domains = ['weibo.com'] keyword_list = ['迪丽热巴'] base_url = 'https://s.weibo.com' start_date = '2020-03-01' end_date = '2020-03-01'

search.py里只需要改动日期和关键字

然后在根目录里运行 scarpy crawl search

就可以了吧?

barnett2010 commented 4 years ago

报错 2020-03-31 19:31:31 [scrapy.core.scraper] ERROR: Spider error processing <GET https://s.weibo.com/weibo?q=%E8%BF%AA%E4%B8%BD%E7%83%AD%E5%B7%B4&region=custom:34: 1000&typeall=1&suball=1&timescope=custom:2020-03-01-9:2020-03-01-10&page=1> (ref erer: https://s.weibo.com/weibo?q=%E8%BF%AA%E4%B8%BD%E7%83%AD%E5%B7%B4&typeall=1 &suball=1&timescope=custom:2020-03-01-9:2020-03-01-10&page=1)

正常 2020-03-31 19:32:52 [scrapy.core.scraper] WARNING: Dropped: Duplicate item foun

barnett2010 commented 4 years ago

脚本太给力了,在微博搜索只能出50页结果。1000条 脚本则可以从一天的0:00--到23.59全都下载到。 2828条

限定搜索3月1日。结果中也会有3月1日前的,结果有100多左右。不过可以时间排序手动删除。

dataabc commented 4 years ago

感谢反馈。

这个程序是个半成品,或者半半成品,还有很多没有写完,以后会继续完善。因为可以按时间和地点来获取,对应某些比较热的关键词,每次都能获取1000个结果,结合地点和时间,最多1天可能获得几百万条微博,这里的一天是我们设置的时间范围而不是说要获取几百万微博需要一天时间,具体时间还要看获取的速度。现在为了调试方便,只默认只获取安徽合肥的微博。还有几百个地方,所以能够获取的数量是现在的几百倍。所以对于大部分关键字都可以获取全部或接近全部的微博,非常热的微博关键词最多24小时的范围能够获取几百万个。

因为现在只是获取全部微博,包含原创和转发。有很多重复的转发。搜索3月1日的,出现3月1日之前的是因为这些是转发微博。关键字可能包含在转发它们的那些转发理由里,那些微博是3月1日的,而这些只是为了获取完整数据顺带获取的。因为转发微博发布在前,所以它们的发布时间可能早于3月1日。

现在程序应该还有很多问题,比如要获取的太多(一天的时间范围可能有几百万要获取),但是为了防止被限,速度过慢,可以需要分布式爬取等待,还有写数据库,下载文件等很多功能没有实现,以后会慢慢优化。

barnett2010 commented 4 years ago

@dataabc 大佬辛苦啦

使用了一下6号最新版。 参数设置整合到一个文件中很方便。

有几个功能提议: 像weibocrawler一样, 增加图片视频的下载开关,1,0。下载或不下载。 增加搜索结果中的原创或转发的下载开关,只下载原创,或都下。

下载的图/视文件,存在依关键字生成的目录下。csv同一目录中 FILES_STORE = './关键字/视频'

dataabc commented 4 years ago

感谢反馈,这些都在计划中,还行一些东西需要弄,会陆续完善。

另外,如果你不想下载图片,可以注释掉setting.py如下代码:

ITEM_PIPELINES = {
    'weibo.pipelines.DuplicatesPipeline': 300,
    'weibo.pipelines.CsvPipeline': 301,
    'weibo.pipelines.MongoPipeline': 302,
    # 'weibo.pipelines.MyImagesPipeline': 303,
    'weibo.pipelines.MyVideoPipeline': 304
}

第一个是去重的,第二个是写csv的,第三个是写MongDB的,第四个是下载图片,第五个是下载视频的。如果哪个不需要,注释掉就好。

barnett2010 commented 4 years ago

使用的是11号的新版本 设置文件中,改动了这几处

'weibo.pipelines.MysqlPipeline': 302,

MYSQL_HOST = 'localhost' MYSQL_PORT = 3306 MYSQL_USER = 'root' MYSQL_PASSWORD = '' MYSQL_DATABASE = 'weibosearch'

然后cmd里执行

E:\e\weibosearch>scrapy crawl search -s JOBDIR=crawls/search

会提示这样一个错误

Traceback (most recent call last): File "c:\python37\lib\runpy.py", line 193, in _run_module_as_main "main", mod_spec) File "c:\python37\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "C:\Python37\Scripts\scrapy.exe__main.py", line 9, in File "c:\python37\lib\site-packages\scrapy\cmdline.py", line 113, in execute settings = get_projectsettings() File "c:\python37\lib\site-packages\scrapy\utils\project.py", line 69, in get project_settings settings.setmodule(settings_module_path, priority='project') File "c:\python37\lib\site-packages\scrapy\settings__init__.py", line 287, in setmodule module = import_module(module) File "c:\python37\lib\importlib\init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "", line 1006, in _gcd_import File "", line 983, in _find_and_load File "", line 967, in _find_and_load_unlocked File "", line 677, in _load_unlocked File "", line 724, in exec_module File "", line 860, in get_code File "", line 791, in source_to_code File "", line 219, in _call_with_frames_removed File "E:\e\weibosearch\weibo\settings.py", line 41 MYSQL_HOST = 'localhost' ^ IndentationError: unexpected indent

================== 又去检查了一下,和上面的设置项对比。 发现mysql那几行设置,不能只删除# 还要删除#后面的空格。才能正常运行。

文本编辑器Notepad++,设置,可以显示所有的字符的。 在: 视图 -> 显示符号 -> 显示空格与制表符

============ 特发上来,给遇到同样问题的人参考。

==== 设置项越来越多,搜索结果很精确。感谢大佬

barnett2010 commented 4 years ago

@dataabc 大佬,有个疑问 ctrl+c 来保存进度这个功能。 是不是说,我在运行$ scrapy crawl search -s JOBDIR=crawls/search 这个命令后,立马按一次ctrl+c 它就会一直保存进度,到我手动停止的那个时间点。 保存进度是自动进行的。

还是说,在我手动关闭cmd前,按一次,它才保存此时间点的进度。

dataabc commented 4 years ago

运行就是scrapy crawl search -s JOBDIR=crawls/search, 当你想关闭程序的时候,按一次ctrl+c,它会继续运行一会,保存一些信息,等所有信息保存,它会自动结束。

Forkeep commented 4 years ago

self.size, = struct.unpack(self.SIZE_FORMAT, qsize) struct.error: unpack requires a buffer of 4 bytes 为什么会出现这个情况

dataabc commented 4 years ago

@Forkeep 可以参考https://github.com/scrapy/scrapy/issues/3413

Forkeep commented 4 years ago

@dataabc 谢谢

modun commented 4 years ago

请问作者,爬取微博的时候可以屏蔽掉某些关键字吗?爬取的时候发现匹配到好多无用的信息,想爬取的更精确些。谢谢!

dataabc commented 4 years ago

@modun 可以判断微博文本是否包含某些关键词,若包含就丢弃。 修改piplines.py->DuplicatesPipeline,将process_item方法改成如下代码即可:

    def process_item(self, item, spider):
        some_words = ['要屏蔽的词A', '要屏蔽的词B']
        for word in some_words:
            if word in item['weibo']['text']:
                raise DropItem("过滤不满足关键词的微博: %s" % item)
        if item['weibo']['id'] in self.ids_seen:
            raise DropItem("过滤重复微博: %s" % item)
        else:
            self.ids_seen.add(item['weibo']['id'])
            return item

some_words代表你想屏蔽的关键词,可以按自己的需要设置,也可以根据文本长度等筛选; 或者使用下面的方法只获取包含完整关键词的微博

    def process_item(self, item, spider):
        keywords = item['keyword'].split(' ')
        for keyword in keywords:
            if keyword not in item['weibo']['text']:
                raise DropItem("过滤不满足关键词的微博: %s" % item)
        if item['weibo']['id'] in self.ids_seen:
            raise DropItem("过滤重复微博: %s" % item)
        else:
            self.ids_seen.add(item['weibo']['id'])
            return item
modun commented 4 years ago

@modun 可以判断微博文本是否包含某些关键词,若包含就丢弃。 修改piplines.py->DuplicatesPipeline,将process_item方法改成如下代码即可:

    def process_item(self, item, spider):
        some_words = ['要屏蔽的词A', '要屏蔽的词B']
        for word in some_words:
            if word in item['weibo']['text']:
                raise DropItem("过滤不满足关键词的微博: %s" % item)
        if item['weibo']['id'] in self.ids_seen:
            raise DropItem("过滤重复微博: %s" % item)
        else:
            self.ids_seen.add(item['weibo']['id'])
            return item

some_words代表你想屏蔽的关键词,可以按自己的需要设置,也可以根据文本长度等筛选; 或者使用下面的方法只获取包含完整关键词的微博

    def process_item(self, item, spider):
        keywords = item['keyword'].split(' ')
        for keyword in keywords:
            if keyword not in item['weibo']['text']:
                raise DropItem("过滤不满足关键词的微博: %s" % item)
        if item['weibo']['id'] in self.ids_seen:
            raise DropItem("过滤重复微博: %s" % item)
        else:
            self.ids_seen.add(item['weibo']['id'])
            return item

谢谢作者!

modun commented 4 years ago

DOWNLOAD_DELAY代表访问完一个页面再访问下一个时需要等待的时间,默认为10秒;

请问作者,页面间隔可以调整成0吗?如果时间太短是否有被封号的风险。谢谢!

dataabc commented 4 years ago

@modun 不建议设为0。 太快了容易被限制,封不封号我也不清楚,最好用小号作爬虫

DeadPoetSpoon commented 4 years ago

请问作者可以限制每次爬取的数据量吗?

dataabc commented 4 years ago

@DeadPoetSpoon 限制数据量的意思是不是不如可以获取100万个结果,限制成10万之类的吗?因为数量大爬不完吗?如果是这样,使用

scrapy crawl search -s JOBDIR=crawls/search

运行,不想爬了按一次Ctrl + c等待停止,下次再运行相同的命令,就能接着上次的继续爬了

DeadPoetSpoon commented 4 years ago

@DeadPoetSpoon 限制数据量的意思是不是不如可以获取100万个结果,限制成10万之类的吗?因为数量大爬不完吗?如果是这样,使用

scrapy crawl search -s JOBDIR=crawls/search

运行,不想爬了按一次Ctrl + c等待停止,下次再运行相同的命令,就能接着上次的继续爬了

明白!谢谢啦!我需要分省的数据,时间范围很长,每次全部都爬完,耗费的时间太久了!

Fxq1997 commented 4 years ago

建议入库时加个字段区分关键词,多个关键词的时候不好区分了。

dataabc commented 4 years ago

@Fxq1997

感谢建议。现在的数据库和weibo-crawler项目的weibo表结构完全一致,因为考虑到联通性,就没有添加关键词字段。如果要筛选关键词,可以通过sql语句筛选。但是加上关键词字段确实更方便,这里还有点纠结。。

AAAKgold commented 4 years ago

@modun 可以判断微博文本是否包含某些关键词,若包含就丢弃。 修改piplines.py->DuplicatesPipeline,将process_item方法改成如下代码即可:

    def process_item(self, item, spider):
        some_words = ['要屏蔽的词A', '要屏蔽的词B']
        for word in some_words:
            if word in item['weibo']['text']:
                raise DropItem("过滤不满足关键词的微博: %s" % item)
        if item['weibo']['id'] in self.ids_seen:
            raise DropItem("过滤重复微博: %s" % item)
        else:
            self.ids_seen.add(item['weibo']['id'])
            return item

some_words代表你想屏蔽的关键词,可以按自己的需要设置,也可以根据文本长度等筛选; 或者使用下面的方法只获取包含完整关键词的微博

    def process_item(self, item, spider):
        keywords = item['keyword'].split(' ')
        for keyword in keywords:
            if keyword not in item['weibo']['text']:
                raise DropItem("过滤不满足关键词的微博: %s" % item)
        if item['weibo']['id'] in self.ids_seen:
            raise DropItem("过滤重复微博: %s" % item)
        else:
            self.ids_seen.add(item['weibo']['id'])
            return item

请问 完整关键词 是什么? ‘迪丽热巴’

dataabc commented 4 years ago

@AAAKgold

可以是任意关键词,如['迪丽热巴 鹿晗'],代码会自动筛选,把不同时包含迪丽热巴和鹿晗的去掉