Chr*_*ris 2 python sqlalchemy scrapy
在 python 2.x 环境中使用 Scrapy,我设置了一个爬虫来抓取网页列表,特别是查看是否有任何页面产生错误,例如 400/404/500。
我编写了scrapy 项目,目的是通过管道将所有抓取的结果存储在mysql 数据库中。它有效!我能够成功写入我的数据库。但仅限于成功抓取的页面,HTTP 状态代码为 200。
Scrapy 似乎没有通过管道将 404 页上的信息发送到数据库中。
下面是从蜘蛛的代码中提取的,它抓取了两个不存在的网页:
class LandingPage004Spider(scrapy.Spider):
name='LandingPage004Spider'
start_urls = []
def __init__(self):
super(LandingPage004Spider,self).__init__()
#self.start_urls = unique_landingpages
self.start_urls = ['https://www.google.com/doesntexist', 'https://www.google.com/deadpage']
def parse(self, response):
url = response.url
url_title = 'Title goes here.'
pagesize = len(response.body)
HTTP_code = response.status
yield {'url': url, "pagesize": pagesize, "HTTP_code": HTTP_code}
Run Code Online (Sandbox Code Playgroud)
当我运行这个蜘蛛时,我得到以下输出:
[scrapy] DEBUG: Ignoring response <404 https://www.google.com/deadpage>: HTTP status code is not handled or not allowed
[scrapy] DEBUG: Ignoring response <404 https://www.google.com/doesntexist>: HTTP status code is not handled or not allowed
Run Code Online (Sandbox Code Playgroud)
现在,我对此进行了大量搜索,似乎这可能是故意的,并且有一种方法可以强制scrapy 包含 404。我看到有一个选项dont_filter,但我只能找到有关如何将该代码附加到类似于以下代码语法的说明: yield Request(url="test.com", callback=self.callback, dont_filter = True)
但是我的蜘蛛结构似乎不允许任何这样的线。
我是否正确地认为 404 没有被发送到数据库,按设计?有没有办法附加我当前的代码以允许记录 404?
如果有帮助,这里是 pipelines.py 文件:
from sqlalchemy.orm import sessionmaker
from LandingPageVerifier.models import LandingPagesScrapeResults, db_connect
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.engine import create_engine
Base = declarative_base()
class Landingpageverifier004Pipeline(object):
def __init__(self):
"""
Initializes database connection and sessionmaker.
"""
engine = db_connect()
self.Session = sessionmaker(bind=engine)
def process_item(self, item, spider):
session = self.Session()
landingpage_scrape_results = LandingPagesScrapeResults()
landingpage_scrape_results.url = item["url"]
landingpage_scrape_results.client_id = 1
landingpage_scrape_results.HTTP_code = item["HTTP_code"]
landingpage_scrape_results.page_size = item["pagesize"]
try:
session.add(landingpage_scrape_results)
session.commit()
except:
session.rollback()
raise
finally:
session.close()
return item
Run Code Online (Sandbox Code Playgroud)
和我的models.py文件的摘录:
class LandingPagesScrapeResults(Base):
__tablename__ = 'landingpages_scrape_results'
id = Column(Integer(), primary_key=True)
client_id = Column(Integer(), ForeignKey('landingpages_clients.id'))
url = Column(String(512), nullable=True)
url_shortener = Column(String(32), nullable=True)
url_title = Column(String(256), nullable=True)
page_size = Column(Integer(), nullable=True)
created_on = Column(DateTime(),default=datetime.datetime.now)
HTTP_code = Column(String(4), nullable=True)
err_small = Column(String(1), nullable=True)
err_has_not_found = Column(String(1), nullable=True)
err_has_error = Column(String(1), nullable=True)
err_has_nolongeravailable = Column(String(1), nullable=True)
err_no_service_specials = Column(String(1), nullable=True)
Run Code Online (Sandbox Code Playgroud)
@stranac 当然给出了一个很好的答案,但您也可以直接使用errbackRequest 属性处理这个问题,它会捕获所有错误的响应,特别是在您需要它的请求中:
def parse(self, response):
yield Request(
'http://httpbin.org/status/404',
errback=self.parse_error,
callback=self.parse_item,
)
def parse_error(self, failure):
if failure.value.response.status == 404:
# insert item as a bad response
def parse_item(self, response):
# insert item as good response
Run Code Online (Sandbox Code Playgroud)
或者,您当然也可以始终使用中间件,在收到后立即捕获各种响应/请求。
| 归档时间: |
|
| 查看次数: |
864 次 |
| 最近记录: |